Merge commit '78c58c24158e3ee4fd78318194d56591af90da69' into lgtm.com

This commit is contained in:
Arthur Baars
2020-10-15 10:00:43 +02:00
543 changed files with 17176 additions and 2752 deletions

View File

@@ -3,8 +3,8 @@
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"github.vscode-codeql"
"GitHub.vscode-codeql"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": []
}
}

View File

@@ -4,20 +4,26 @@ The following changes in version 1.25 affect Java analysis in all applications.
## General improvements
## New queries
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
The Java autobuilder has been improved to detect more Gradle Java versions.
## Changes to existing queries
| **Query** | **Expected impact** | **Change** |
|------------------------------|------------------------|-----------------------------------|
| Hard-coded credential in API call (`java/hardcoded-credential-api-call`) | More results | The query now recognizes the `BasicAWSCredentials` class of the Amazon client SDK library with hardcoded access key/secret key. |
| Deserialization of user-controlled data (`java/unsafe-deserialization`) | Fewer false positive results | The query no longer reports results using `org.apache.commons.io.serialization.ValidatingObjectInputStream`. |
| Use of a broken or risky cryptographic algorithm (`java/weak-cryptographic-algorithm`) | More results | The query now recognizes the `MessageDigest.getInstance` method. |
| Use of a potentially broken or risky cryptographic algorithm (`java/potentially-weak-cryptographic-algorithm`) | More results | The query now recognizes the `MessageDigest.getInstance` method. |
| Reading from a world writable file (`java/world-writable-file-read`) | More results | The query now recognizes more JDK file operations. |
## Changes to libraries
* The data-flow library has been improved with more taint flow modeling for the
Collections framework and other classes of the JDK. This affects all security
queries using data flow and can yield additional results.
* The data-flow library has been improved with more taint flow modeling for the
Spring framework. This affects all security queries using data flow and can
yield additional results on project that rely on the Spring framework.
* The data-flow library has been improved, which affects most security queries by potentially
adding more results. Flow through methods now takes nested field reads/writes into account.
For example, the library is able to track flow from `"taint"` to `sink()` via the method
@@ -39,3 +45,5 @@ The following changes in version 1.25 affect Java analysis in all applications.
}
}
```
* The library has been extended with more support for Java 14 features
(`switch` expressions and pattern-matching for `instanceof`).

View File

@@ -1,22 +1,9 @@
# Improvements to Python analysis
The following changes in version 1.25 affect Python analysis in all applications.
## General improvements
## New queries
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
## Changes to existing queries
| **Query** | **Expected impact** | **Change** |
|----------------------------|------------------------|------------------------------------------------------------------|
## Changes to libraries
* Importing `semmle.python.web.HttpRequest` will no longer import `UntrustedStringKind` transitively. `UntrustedStringKind` is the most commonly used non-abstract subclass of `ExternalStringKind`. If not imported (by one mean or another), taint-tracking queries that concern `ExternalStringKind` will not produce any results. Please ensure such queries contain an explicit import (`import semmle.python.security.strings.Untrusted`).
* Added model of taint sources for HTTP servers using `http.server`.
* Added taint modeling of routed parameters in Flask.
* Improved modeling of built-in methods on strings for taint tracking.
* Improved classification of test files.
* New class `BoundMethodValue` represents a bound method during runtime.
* The query `py/command-line-injection` now recognizes command execution with the `fabric` and `invoke` Python libraries.

View File

@@ -23,7 +23,7 @@ The following changes in version 1.26 affect C/C++ analysis in all applications.
* The QL class `Block`, denoting the `{ ... }` statement, is renamed to `BlockStmt`.
* The models library now models many taint flows through `std::array`, `std::vector`, `std::deque`, `std::list` and `std::forward_list`.
* The models library now models many more taint flows through `std::string`.
* The models library now models some taint flows through `std::ostream`.
* The models library now models many taint flows through `std::istream` and `std::ostream`.
* The models library now models some taint flows through `std::shared_ptr`, `std::unique_ptr`, `std::make_shared` and `std::make_unique`.
* The `SimpleRangeAnalysis` library now supports multiplications of the form
`e1 * e2` and `x *= e2` when `e1` and `e2` are unsigned or constant.

View File

@@ -12,7 +12,7 @@ The following changes in version 1.26 affect C# analysis in all applications.
| **Query** | **Expected impact** | **Change** |
|------------------------------|------------------------|-----------------------------------|
| Weak encryption: Insufficient key size (`cs/insufficient-key-size`) | More results | The required key size has been increased from 1024 to 2048. |
## Removal of old queries

View File

@@ -4,20 +4,24 @@
* Support for the following frameworks and libraries has been improved:
- [bluebird](https://www.npmjs.com/package/bluebird)
- [express](https://www.npmjs.com/package/express)
- [fast-json-stable-stringify](https://www.npmjs.com/package/fast-json-stable-stringify)
- [fast-safe-stringify](https://www.npmjs.com/package/fast-safe-stringify)
- [http](https://nodejs.org/api/http.html)
- [javascript-stringify](https://www.npmjs.com/package/javascript-stringify)
- [js-stringify](https://www.npmjs.com/package/js-stringify)
- [json-stable-stringify](https://www.npmjs.com/package/json-stable-stringify)
- [json-stringify-safe](https://www.npmjs.com/package/json-stringify-safe)
- [json3](https://www.npmjs.com/package/json3)
- [lodash](https://www.npmjs.com/package/lodash)
- [needle](https://www.npmjs.com/package/needle)
- [object-inspect](https://www.npmjs.com/package/object-inspect)
- [pretty-format](https://www.npmjs.com/package/pretty-format)
- [stringify-object](https://www.npmjs.com/package/stringify-object)
- [underscore](https://www.npmjs.com/package/underscore)
* Analyzing files with the ".cjs" extension is now supported.
* ES2021 features are now supported.
## New queries
@@ -35,6 +39,8 @@
| Unused loop iteration variable (`js/unused-loop-variable`) | Fewer results | This query no longer flags variables in a destructuring array assignment that are not the last variable in the destructed array. |
| Unsafe shell command constructed from library input (`js/shell-command-constructed-from-input`) | More results | This query now recognizes more commands where colon, dash, and underscore are used. |
| Unsafe jQuery plugin (`js/unsafe-jquery-plugin`) | More results | This query now detects more unsafe uses of nested option properties. |
| Client-side URL redirect (`js/client-side-unvalidated-url-redirection`) | More results | This query now recognizes some unsafe uses of `importScripts()` inside WebWorkers. |
| Missing CSRF middleware (`js/missing-token-validation`) | More results | This query now recognizes writes to cookie and session variables as potentially vulnerable to CSRF attacks. |
## Changes to libraries

View File

@@ -50,6 +50,18 @@
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll",
"python/ql/src/experimental/dataflow/internal/DataFlowImplConsistency.qll"
],
"SsaReadPosition Java/C#": [
"java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll"
],
"Sign Java/C#": [
"java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/Sign.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/Sign.qll"
],
"SignAnalysis Java/C#": [
"java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll"
],
"C++ SubBasicBlocks": [
"cpp/ql/src/semmle/code/cpp/controlflow/SubBasicBlocks.qll",
"cpp/ql/src/semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll"
@@ -87,7 +99,7 @@
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll",
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll",
"csharp/ql/src/experimental/ir/implementation/raw/Operand.qll",
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Operand.qll"
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Operand.qll"
],
"IR IRType": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/IRType.qll",
@@ -109,11 +121,11 @@
"cpp/ql/src/semmle/code/cpp/ir/implementation/internal/OperandTag.qll",
"csharp/ql/src/experimental/ir/implementation/internal/OperandTag.qll"
],
"IR TInstruction":[
"IR TInstruction": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/internal/TInstruction.qll",
"csharp/ql/src/experimental/ir/implementation/internal/TInstruction.qll"
],
"IR TIRVariable":[
"IR TIRVariable": [
"cpp/ql/src/semmle/code/cpp/ir/implementation/internal/TIRVariable.qll",
"csharp/ql/src/experimental/ir/implementation/internal/TIRVariable.qll"
],
@@ -381,4 +393,4 @@
"javascript/ql/src/Comments/CommentedOutCodeReferences.qhelp",
"python/ql/src/Lexical/CommentedOutCodeReferences.qhelp"
]
}
}

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name External dependencies
* @description Count the number of dependencies a C/C++ source file has on external libraries.
* @kind treemap

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name External dependency source links
* @kind source-link
* @metricType externalDependency

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicated lines in files
* @description The number of lines in a file, including code, comment
* and whitespace lines, which are duplicated in at least

View File

@@ -39,7 +39,7 @@ access all the system's passwords.</p>
<li>
OWASP:
<a href="https://www.owasp.org/index.php/Path_traversal">Path Traversal</a>.
<a href="https://owasp.org/www-community/attacks/Path_Traversal">Path Traversal</a>.
</li>
</references>

View File

@@ -9,10 +9,7 @@
tags contain:
- ide-contextual-queries/local-definitions
- ide-contextual-queries/local-references
- query: Metrics/Dependencies/ExternalDependencies.ql
- query: Metrics/Dependencies/ExternalDependenciesSourceLinks.ql
- query: Metrics/Files/FLinesOfCode.ql
- query: Metrics/Files/FLinesOfCommentedOutCode.ql
- query: Metrics/Files/FLinesOfComments.ql
- query: Metrics/Files/FLinesOfDuplicatedCode.ql
- query: Metrics/Files/FNumberOfTests.ql

View File

@@ -0,0 +1,65 @@
/**
* EXPERIMENTAL: The API of this module may change without notice.
*
* Provides a class for modeling `RangeSsaDefinition`s with a restricted range.
*/
import cpp
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
/**
* EXPERIMENTAL: The API of this class may change without notice.
*
* An SSA definition for which a range can be deduced. As with
* `RangeSsaDefinition` and `SsaDefinition`, instances of this class
* correspond to points in the program where one or more variables are defined
* or have their value constrained in some way.
*
* Extend this class to add functionality to the range analysis library.
*/
abstract class SimpleRangeAnalysisDefinition extends RangeSsaDefinition {
/**
* Holds if this `SimpleRangeAnalysisDefinition` adds range information for
* `v`. Because a `SimpleRangeAnalysisDefinition` is just a point in the
* program, it's possible that more than one variable might be defined at
* this point. This predicate clarifies which variable(s) should get range
* information from `this`.
*
* This predicate **must be overridden** to hold for any `v` that can show
* up in the other members of `SimpleRangeAnalysisDefinition`. Conversely,
* the other members **must be accurate** for any `v` in this predicate.
*/
abstract predicate hasRangeInformationFor(StackVariable v);
/**
* Holds if `(this, v)` depends on the range of the unconverted expression
* `e`. This information is used to inform the range analysis about cyclic
* dependencies. Without this information, range analysis might work for
* simple cases but will go into infinite loops on complex code.
*
* For example, when modelling the definition by reference in a call to an
* overloaded `operator=`, written as `v = e`, the definition of `(this, v)`
* depends on `e`.
*/
abstract predicate dependsOnExpr(StackVariable v, Expr e);
/**
* Gets the lower bound of the variable `v` defined by this definition.
*
* Implementations of this predicate should use
* `getFullyConvertedLowerBounds` and `getFullyConvertedUpperBounds` for
* recursive calls to get the bounds of their dependencies.
*/
abstract float getLowerBounds(StackVariable v);
/**
* Gets the upper bound of the variable `v` defined by this definition.
*
* Implementations of this predicate should use
* `getFullyConvertedLowerBounds` and `getFullyConvertedUpperBounds` for
* recursive calls to get the bounds of their dependencies.
*/
abstract float getUpperBounds(StackVariable v);
}
import SimpleRangeAnalysisInternal

View File

@@ -0,0 +1,4 @@
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
//
// Import each extension we want to enable
import extensions.SubtractSelf

View File

@@ -0,0 +1,15 @@
import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr
private class SelfSub extends SimpleRangeAnalysisExpr, SubExpr {
SelfSub() {
// Match `x - x` but not `myInt - (unsigned char)myInt`.
getLeftOperand().getExplicitlyConverted().(VariableAccess).getTarget() =
getRightOperand().getExplicitlyConverted().(VariableAccess).getTarget()
}
override float getLowerBounds() { result = 0 }
override float getUpperBounds() { result = 0 }
override predicate dependsOnChild(Expr child) { none() }
}

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicate code
* @description This block of code is duplicated elsewhere. If possible, the shared code should be refactored so there is only one occurrence left. It may not always be possible to address these issues; other duplicate code checks (such as duplicate function, duplicate class) give subsets of the results with higher confidence.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicate function
* @description There is another identical implementation of this function. Extract the code to a common file or superclass or delegate to improve sharing.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Mostly duplicate class
* @description More than 80% of the methods in this class are duplicated in another class. Create a common supertype to improve code sharing.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Mostly duplicate file
* @description There is another file that shares a lot of the code with this file. Merge the two files to improve maintainability.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Mostly duplicate function
* @description There is another function that shares a lot of the code with this one. Extract the code to a common file/superclass or delegate to improve sharing.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Mostly similar file
* @description There is another file that shares a lot of the code with this file. Notice that names of variables and types may have been changed. Merge the two files to improve maintainability.
* @kind problem

View File

@@ -144,6 +144,11 @@ class Variable extends Declaration, @variable {
*/
predicate isConstexpr() { this.hasSpecifier("is_constexpr") }
/**
* Holds if this variable is declared `constinit`.
*/
predicate isConstinit() { this.hasSpecifier("declared_constinit") }
/**
* Holds if this variable is `thread_local`.
*/

View File

@@ -279,20 +279,62 @@ private predicate reachableRecursive(ControlFlowNode n) {
reachableRecursive(n.getAPredecessor())
}
/** Holds if `e` is a compile time constant with integer value `val`. */
private predicate compileTimeConstantInt(Expr e, int val) {
val = e.getFullyConverted().getValue().toInt() and
not e instanceof StringLiteral and
not exists(Expr e1 | e1.getConversion() = e) // only values for fully converted expressions
(
// If we have an integer value then we are done.
if exists(e.getValue().toInt())
then val = e.getValue().toInt()
else
// Otherwise, if we are a conversion of another expression with an
// integer value, and that value can be converted into our type,
// then we have that value.
exists(Expr x, int valx |
x.getConversion() = e and
compileTimeConstantInt(x, valx) and
val = convertIntToType(valx, e.getType().getUnspecifiedType())
)
) and
// If our unconverted expression is a string literal `"123"`, then we
// do not have integer value `123`.
not e.getUnconverted() instanceof StringLiteral
}
library class CompileTimeConstantInt extends Expr {
CompileTimeConstantInt() { compileTimeConstantInt(this, _) }
/**
* Get `val` represented as type `t`, if that is possible without
* overflow or underflows.
*/
bindingset[val, t]
private int convertIntToType(int val, IntegralType t) {
if t instanceof BoolType
then if val = 0 then result = 0 else result = 1
else
if t.isUnsigned()
then if val >= 0 and val.bitShiftRight(t.getSize() * 8) = 0 then result = val else none()
else
if val >= 0 and val.bitShiftRight(t.getSize() * 8 - 1) = 0
then result = val
else
if (-(val + 1)).bitShiftRight(t.getSize() * 8 - 1) = 0
then result = val
else none()
}
int getIntValue() { compileTimeConstantInt(this, result) }
/**
* INTERNAL: Do not use.
* An expression that has been found to have an integer value at compile
* time.
*/
class CompileTimeConstantInt extends Expr {
int val;
CompileTimeConstantInt() { compileTimeConstantInt(this.getFullyConverted(), val) }
int getIntValue() { result = val }
}
library class CompileTimeVariableExpr extends Expr {
CompileTimeVariableExpr() { not compileTimeConstantInt(this, _) }
CompileTimeVariableExpr() { not this instanceof CompileTimeConstantInt }
}
/** A helper class for evaluation of expressions. */

View File

@@ -29,7 +29,7 @@ private predicate stdIdentityFunction(Function f) { f.hasQualifiedName("std", ["
*/
private predicate stdAddressOf(Function f) { f.hasQualifiedName("std", "addressof") }
private predicate lvalueToLvalueStep(Expr lvalueIn, Expr lvalueOut) {
private predicate lvalueToLvalueStepPure(Expr lvalueIn, Expr lvalueOut) {
lvalueIn.getConversion() = lvalueOut.(ParenthesisExpr)
or
// When an object is implicitly converted to a reference to one of its base
@@ -42,6 +42,10 @@ private predicate lvalueToLvalueStep(Expr lvalueIn, Expr lvalueOut) {
// such casts.
lvalueIn.getConversion() = lvalueOut and
lvalueOut.(CStyleCast).isImplicit()
}
private predicate lvalueToLvalueStep(Expr lvalueIn, Expr lvalueOut) {
lvalueToLvalueStepPure(lvalueIn, lvalueOut)
or
// C++ only
lvalueIn = lvalueOut.(PrefixCrementOperation).getOperand().getFullyConverted()
@@ -214,6 +218,69 @@ private predicate referenceToUpdate(Expr reference, Expr outer, ControlFlowNode
)
}
private predicate lvalueFromVariableAccess(VariableAccess va, Expr lvalue) {
// Base case for non-reference types.
lvalue = va and
not va.getConversion() instanceof ReferenceDereferenceExpr
or
// Base case for reference types where we pretend that they are
// non-reference types. The type of the target of `va` can be `ReferenceType`
// or `FunctionReferenceType`.
lvalue = va.getConversion().(ReferenceDereferenceExpr)
or
// lvalue -> lvalue
exists(Expr prev |
lvalueFromVariableAccess(va, prev) and
lvalueToLvalueStep(prev, lvalue)
)
or
// pointer -> lvalue
exists(Expr prev |
pointerFromVariableAccess(va, prev) and
pointerToLvalueStep(prev, lvalue)
)
or
// reference -> lvalue
exists(Expr prev |
referenceFromVariableAccess(va, prev) and
referenceToLvalueStep(prev, lvalue)
)
}
private predicate pointerFromVariableAccess(VariableAccess va, Expr pointer) {
// pointer -> pointer
exists(Expr prev |
pointerFromVariableAccess(va, prev) and
pointerToPointerStep(prev, pointer)
)
or
// reference -> pointer
exists(Expr prev |
referenceFromVariableAccess(va, prev) and
referenceToPointerStep(prev, pointer)
)
or
// lvalue -> pointer
exists(Expr prev |
lvalueFromVariableAccess(va, prev) and
lvalueToPointerStep(prev, pointer)
)
}
private predicate referenceFromVariableAccess(VariableAccess va, Expr reference) {
// reference -> reference
exists(Expr prev |
referenceFromVariableAccess(va, prev) and
referenceToReferenceStep(prev, reference)
)
or
// lvalue -> reference
exists(Expr prev |
lvalueFromVariableAccess(va, prev) and
lvalueToReferenceStep(prev, reference)
)
}
/**
* Holds if `node` is a control-flow node that may modify `inner` (or what it
* points to) through `outer`. The two expressions may be `Conversion`s. Plain
@@ -236,7 +303,7 @@ predicate valueToUpdate(Expr inner, Expr outer, ControlFlowNode node) {
(
inner instanceof VariableAccess and
// Don't track non-field assignments
(assignmentTo(outer, _) implies inner instanceof FieldAccess)
not (assignmentTo(outer, _) and outer.(VariableAccess).getTarget() instanceof StackVariable)
or
inner instanceof ThisExpr
or
@@ -245,3 +312,27 @@ predicate valueToUpdate(Expr inner, Expr outer, ControlFlowNode node) {
// can't do anything useful with those at the moment.
)
}
/**
* Holds if `e` is a fully-converted expression that evaluates to an lvalue
* derived from `va` and is used for reading from or assigning to. This is in
* contrast with a variable access that is used for taking an address (`&x`)
* or simply discarding its value (`x;`).
*
* This analysis does not propagate across assignments or calls, and unlike
* `variableAccessedAsValue` in `semmle.code.cpp.dataflow.EscapesTree` it
* propagates through array accesses but not field accesses. The analysis is
* also not concerned with whether the lvalue `e` is converted to an rvalue --
* to examine that, use the relevant member predicates on `Expr`.
*
* If `va` has reference type, the analysis concerns the value pointed to by
* the reference rather than the reference itself. The expression `e` may be a
* `Conversion`.
*/
predicate variablePartiallyAccessed(VariableAccess va, Expr e) {
lvalueFromVariableAccess(va, e) and
not lvalueToLvalueStepPure(e, _) and
not lvalueToPointerStep(e, _) and
not lvalueToReferenceStep(e, _) and
not e = any(ExprInVoidContext eivc | e = eivc.getConversion*())
}

View File

@@ -1,6 +1,7 @@
private import cpp
private import DataFlowUtil
private import DataFlowDispatch
private import FlowVar
/** Gets the instance argument of a non-static call. */
private Node getInstanceArgument(Call call) {
@@ -106,7 +107,7 @@ private class ExprOutNode extends OutNode, ExprNode {
override DataFlowCall getCall() { result = this.getExpr() }
}
private class RefOutNode extends OutNode, DefinitionByReferenceNode {
private class RefOutNode extends OutNode, DefinitionByReferenceOrIteratorNode {
/** Gets the underlying call. */
override DataFlowCall getCall() { result = this.getArgument().getParent() }
}
@@ -120,7 +121,7 @@ OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
kind = TNormalReturnKind()
or
exists(int i |
result.asDefiningArgument() = call.getArgument(i) and
result.(DefinitionByReferenceOrIteratorNode).getArgument() = call.getArgument(i) and
kind = TRefReturnKind(i)
)
}

View File

@@ -6,6 +6,7 @@ private import cpp
private import semmle.code.cpp.dataflow.internal.FlowVar
private import semmle.code.cpp.models.interfaces.DataFlow
private import semmle.code.cpp.controlflow.Guards
private import semmle.code.cpp.dataflow.internal.AddressFlow
cached
private newtype TNode =
@@ -182,28 +183,29 @@ class ImplicitParameterNode extends ParameterNode, TInstanceParameterNode {
}
/**
* A node that represents the value of a variable after a function call that
* may have changed the variable because it's passed by reference.
* INTERNAL: do not use.
*
* A typical example would be a call `f(&x)`. Firstly, there will be flow into
* `x` from previous definitions of `x`. Secondly, there will be a
* `DefinitionByReferenceNode` to represent the value of `x` after the call has
* returned. This node will have its `getArgument()` equal to `&x`.
* A node that represents the value of a variable after a function call that
* may have changed the variable because it's passed by reference or because an
* iterator for it was passed by value or by reference.
*/
class DefinitionByReferenceNode extends PartialDefinitionNode {
class DefinitionByReferenceOrIteratorNode extends PartialDefinitionNode {
Expr inner;
Expr argument;
DefinitionByReferenceNode() {
this.getPartialDefinition().(DefinitionByReference).definesExpressions(inner, argument)
DefinitionByReferenceOrIteratorNode() {
this.getPartialDefinition().definesExpressions(inner, argument) and
(
this.getPartialDefinition() instanceof DefinitionByReference
or
this.getPartialDefinition() instanceof DefinitionByIterator
)
}
override Function getFunction() { result = inner.getEnclosingFunction() }
override Type getType() { result = inner.getType() }
override string toString() { result = "ref arg " + argument.toString() }
override Location getLocation() { result = argument.getLocation() }
override ExprNode getPreUpdateNode() { result.getExpr() = argument }
@@ -220,6 +222,21 @@ class DefinitionByReferenceNode extends PartialDefinitionNode {
}
}
/**
* A node that represents the value of a variable after a function call that
* may have changed the variable because it's passed by reference.
*
* A typical example would be a call `f(&x)`. Firstly, there will be flow into
* `x` from previous definitions of `x`. Secondly, there will be a
* `DefinitionByReferenceNode` to represent the value of `x` after the call has
* returned. This node will have its `getArgument()` equal to `&x`.
*/
class DefinitionByReferenceNode extends DefinitionByReferenceOrIteratorNode {
override VariablePartialDefinition pd;
override string toString() { result = "ref arg " + argument.toString() }
}
/**
* The value of an uninitialized local variable, viewed as a node in a data
* flow graph.
@@ -283,13 +300,11 @@ abstract class PostUpdateNode extends Node {
override Location getLocation() { result = getPreUpdateNode().getLocation() }
}
private class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNode {
abstract private class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNode {
PartialDefinition pd;
PartialDefinitionNode() { this = TPartialDefinitionNode(pd) }
override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) }
override Location getLocation() { result = pd.getActualLocation() }
PartialDefinition getPartialDefinition() { result = pd }
@@ -297,6 +312,24 @@ private class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNo
override string toString() { result = getPreUpdateNode().toString() + " [post update]" }
}
private class VariablePartialDefinitionNode extends PartialDefinitionNode {
override VariablePartialDefinition pd;
override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) }
}
/**
* INTERNAL: do not use.
*
* A synthetic data flow node used for flow into a collection when an iterator
* write occurs in a callee.
*/
class IteratorPartialDefinitionNode extends PartialDefinitionNode {
override IteratorPartialDefinition pd;
override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) }
}
/**
* A post-update node on the `e->f` in `f(&e->f)` (and other forms).
*/
@@ -610,6 +643,15 @@ private predicate exprToExprStep_nocfg(Expr fromExpr, Expr toExpr) {
or
toExpr.(AddressOfExpr).getOperand() = fromExpr
or
// This rule enables flow from an array to its elements. Example: `a` to
// `a[i]` or `*a`, where `a` is an array type. It does not enable flow from a
// pointer to its indirection as in `p[i]` where `p` is a pointer type.
exists(Expr toConverted |
variablePartiallyAccessed(fromExpr, toConverted) and
toExpr = toConverted.getUnconverted() and
not toExpr = fromExpr
)
or
toExpr.(BuiltInOperationBuiltInAddressOf).getOperand() = fromExpr
or
// The following case is needed to track the qualifier object for flow

View File

@@ -6,6 +6,7 @@ import cpp
private import semmle.code.cpp.controlflow.SSA
private import semmle.code.cpp.dataflow.internal.SubBasicBlocks
private import semmle.code.cpp.dataflow.internal.AddressFlow
private import semmle.code.cpp.models.implementations.Iterator
/**
* A conceptual variable that is assigned only once, like an SSA variable. This
@@ -108,21 +109,12 @@ class FlowVar extends TFlowVar {
* ```
*/
private module PartialDefinitions {
class PartialDefinition extends Expr {
Expr innerDefinedExpr;
abstract class PartialDefinition extends Expr {
ControlFlowNode node;
PartialDefinition() {
exists(Expr convertedInner |
valueToUpdate(convertedInner, this.getFullyConverted(), node) and
innerDefinedExpr = convertedInner.getUnconverted() and
not this instanceof Conversion
)
}
abstract deprecated predicate partiallyDefines(Variable v);
deprecated predicate partiallyDefines(Variable v) { innerDefinedExpr = v.getAnAccess() }
deprecated predicate partiallyDefinesThis(ThisExpr e) { innerDefinedExpr = e }
abstract deprecated predicate partiallyDefinesThis(ThisExpr e);
/**
* Gets the subBasicBlock where this `PartialDefinition` is defined.
@@ -133,11 +125,9 @@ private module PartialDefinitions {
* Holds if this `PartialDefinition` defines variable `v` at control-flow
* node `cfn`.
*/
// does this work with a dispred?
pragma[noinline]
predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) {
innerDefinedExpr = v.getAnAccess() and
cfn = node
}
abstract predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn);
/**
* Holds if this partial definition may modify `inner` (or what it points
@@ -147,10 +137,7 @@ private module PartialDefinitions {
* - `inner` = `... .x`, `outer` = `&...`
* - `inner` = `a`, `outer` = `*`
*/
predicate definesExpressions(Expr inner, Expr outer) {
inner = innerDefinedExpr and
outer = this
}
abstract predicate definesExpressions(Expr inner, Expr outer);
/**
* Gets the location of this element, adjusted to avoid unknown locations
@@ -166,10 +153,107 @@ private module PartialDefinitions {
}
}
class IteratorPartialDefinition extends PartialDefinition {
Variable collection;
Expr innerDefinedExpr;
IteratorPartialDefinition() {
exists(Expr convertedInner |
not this instanceof Conversion and
valueToUpdate(convertedInner, this.getFullyConverted(), node) and
innerDefinedExpr = convertedInner.getUnconverted() and
(
innerDefinedExpr.(Call).getQualifier() = getAnIteratorAccess(collection)
or
innerDefinedExpr.(Call).getQualifier() = collection.getAnAccess() and
collection instanceof IteratorParameter
) and
innerDefinedExpr.(Call).getTarget() instanceof IteratorPointerDereferenceMemberOperator
)
or
// iterators passed by value without a copy constructor
exists(Call call |
call = node and
call.getAnArgument() = innerDefinedExpr and
innerDefinedExpr = this and
this = getAnIteratorAccess(collection) and
not call.getTarget() instanceof IteratorPointerDereferenceMemberOperator
)
or
// iterators passed by value with a copy constructor
exists(Call call, ConstructorCall copy |
copy.getTarget() instanceof CopyConstructor and
call = node and
call.getAnArgument() = copy and
copy.getArgument(0) = getAnIteratorAccess(collection) and
innerDefinedExpr = this and
this = copy and
not call.getTarget() instanceof IteratorPointerDereferenceMemberOperator
)
}
deprecated override predicate partiallyDefines(Variable v) { v = collection }
deprecated override predicate partiallyDefinesThis(ThisExpr e) { none() }
override predicate definesExpressions(Expr inner, Expr outer) {
inner = innerDefinedExpr and
outer = this
}
override predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) {
v = collection and
cfn = node
}
}
class VariablePartialDefinition extends PartialDefinition {
Expr innerDefinedExpr;
VariablePartialDefinition() {
not this instanceof Conversion and
exists(Expr convertedInner |
valueToUpdate(convertedInner, this.getFullyConverted(), node) and
innerDefinedExpr = convertedInner.getUnconverted()
)
}
deprecated override predicate partiallyDefines(Variable v) {
innerDefinedExpr = v.getAnAccess()
}
deprecated override predicate partiallyDefinesThis(ThisExpr e) { innerDefinedExpr = e }
/**
* Holds if this partial definition may modify `inner` (or what it points
* to) through `outer`. These expressions will never be `Conversion`s.
*
* For example, in `f(& (*a).x)`, there are two results:
* - `inner` = `... .x`, `outer` = `&...`
* - `inner` = `a`, `outer` = `*`
*/
override predicate definesExpressions(Expr inner, Expr outer) {
inner = innerDefinedExpr and
outer = this
}
override predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) {
innerDefinedExpr = v.getAnAccess() and
cfn = node
}
}
/**
* A partial definition that's a definition via an output iterator.
*/
class DefinitionByIterator extends IteratorPartialDefinition {
DefinitionByIterator() { exists(Call c | this = c.getAnArgument() or this = c.getQualifier()) }
}
/**
* A partial definition that's a definition by reference.
*/
class DefinitionByReference extends PartialDefinition {
class DefinitionByReference extends VariablePartialDefinition {
DefinitionByReference() { exists(Call c | this = c.getAnArgument() or this = c.getQualifier()) }
}
}
@@ -211,7 +295,8 @@ module FlowVar_internal {
// The SSA library has a theoretically accurate treatment of reference types,
// treating them as immutable, but for data flow it gives better results in
// practice to make the variable synonymous with its contents.
not v.getUnspecifiedType() instanceof ReferenceType
not v.getUnspecifiedType() instanceof ReferenceType and
not v instanceof IteratorParameter
}
/**
@@ -240,7 +325,7 @@ module FlowVar_internal {
(
initializer(v, sbb.getANode())
or
assignmentLikeOperation(sbb, v, _, _)
assignmentLikeOperation(sbb, v, _)
or
exists(PartialDefinition p | p.partiallyDefinesVariableAt(v, sbb))
or
@@ -359,7 +444,7 @@ module FlowVar_internal {
}
override predicate definedByExpr(Expr e, ControlFlowNode node) {
assignmentLikeOperation(node, v, _, e) and
assignmentLikeOperation(node, v, e) and
node = sbb
or
// We pick the defining `ControlFlowNode` of an `Initializer` to be its
@@ -449,7 +534,7 @@ module FlowVar_internal {
pragma[noinline]
private Variable getAVariableAssignedInLoop() {
exists(BasicBlock bbAssign |
assignmentLikeOperation(bbAssign.getANode(), result, _, _) and
assignmentLikeOperation(bbAssign.getANode(), result, _) and
this.bbInLoop(bbAssign)
)
}
@@ -487,7 +572,7 @@ module FlowVar_internal {
pragma[noinline]
private predicate assignsToVar(BasicBlock bb, Variable v) {
assignmentLikeOperation(bb.getANode(), v, _, _) and
assignmentLikeOperation(bb.getANode(), v, _) and
exists(AlwaysTrueUponEntryLoop loop | v = loop.getARelevantVariable())
}
@@ -524,7 +609,7 @@ module FlowVar_internal {
result = mid.getASuccessor() and
variableLiveInSBB(result, v) and
forall(AlwaysTrueUponEntryLoop loop | skipLoop(mid, result, v, loop) | loop.sbbInLoop(sbbDef)) and
not assignmentLikeOperation(result, v, _, _)
not assignmentLikeOperation(result, v, _)
)
}
@@ -560,13 +645,15 @@ module FlowVar_internal {
refType = p.getUnderlyingType() and
not refType.getBaseType().isConst()
)
or
p instanceof IteratorParameter
}
/**
* Holds if liveness of `v` should stop propagating backwards from `sbb`.
*/
private predicate variableNotLiveBefore(SubBasicBlock sbb, Variable v) {
assignmentLikeOperation(sbb, v, _, _)
assignmentLikeOperation(sbb, v, _)
or
// Liveness of `v` is killed when going backwards from a block that declares it
exists(DeclStmt ds | ds.getADeclaration().(LocalVariable) = v and sbb.contains(ds))
@@ -686,21 +773,17 @@ module FlowVar_internal {
* `node instanceof Initializer` is covered by `initializer` instead of this
* predicate.
*/
predicate assignmentLikeOperation(
ControlFlowNode node, Variable v, VariableAccess va, Expr assignedExpr
) {
predicate assignmentLikeOperation(ControlFlowNode node, Variable v, Expr assignedExpr) {
// Together, the two following cases cover `Assignment`
node =
any(AssignExpr ae |
va = ae.getLValue() and
v = va.getTarget() and
v.getAnAccess() = ae.getLValue() and
assignedExpr = ae.getRValue()
)
or
node =
any(AssignOperation ao |
va = ao.getLValue() and
v = va.getTarget() and
v.getAnAccess() = ao.getLValue() and
// Here and in the `PrefixCrementOperation` case, we say that the assigned
// expression is the operation itself. For example, we say that `x += 1`
// assigns `x += 1` to `x`. The justification is that after this operation,
@@ -712,12 +795,24 @@ module FlowVar_internal {
// `PrefixCrementOperation` is itself a source
node =
any(CrementOperation op |
va = op.getOperand() and
v = va.getTarget() and
v.getAnAccess() = op.getOperand() and
assignedExpr = op
)
}
Expr getAnIteratorAccess(Variable collection) {
exists(Call c, SsaDefinition def, Variable iterator |
c.getQualifier() = collection.getAnAccess() and
c.getTarget() instanceof BeginOrEndFunction and
def.getAnUltimateDefiningValue(iterator) = c and
result = def.getAUse(iterator)
)
}
class IteratorParameter extends Parameter {
IteratorParameter() { this.getUnspecifiedType() instanceof Iterator }
}
/**
* Holds if `v` is initialized to have value `assignedExpr`.
*/
@@ -749,7 +844,7 @@ module FlowVar_internal {
class DataFlowSubBasicBlockCutNode extends SubBasicBlockCutNode {
DataFlowSubBasicBlockCutNode() {
exists(Variable v | not fullySupportedSsaVariable(v) |
assignmentLikeOperation(this, v, _, _)
assignmentLikeOperation(this, v, _)
or
exists(PartialDefinition p | p.partiallyDefinesVariableAt(v, this))
// It is not necessary to cut the basic blocks at `Initializer` nodes

View File

@@ -10,6 +10,7 @@
private import semmle.code.cpp.models.interfaces.DataFlow
private import semmle.code.cpp.models.interfaces.Taint
private import semmle.code.cpp.models.interfaces.Iterator
private module DataFlow {
import semmle.code.cpp.dataflow.internal.DataFlowUtil
@@ -255,4 +256,12 @@ private predicate exprToPartialDefinitionStep(Expr exprIn, Expr exprOut) {
exprIn = call.getArgument(argInIndex)
)
)
or
exists(Assignment a |
iteratorDereference(exprOut) and
a.getLValue() = exprOut and
a.getRValue() = exprIn
)
}
private predicate iteratorDereference(Call c) { c.getTarget() instanceof IteratorReferenceFunction }

View File

@@ -264,9 +264,6 @@ private predicate instructionTaintStep(Instruction i1, Instruction i2) {
t instanceof Union
or
t instanceof ArrayType
or
// Buffers of unknown size
t instanceof UnknownType
)
or
exists(BinaryInstruction bin |

View File

@@ -197,28 +197,37 @@ private class CollectionContent extends Content, TCollectionContent {
}
private class ArrayContent extends Content, TArrayContent {
override string toString() { result = "array" }
ArrayContent() { this = TArrayContent() }
override string toString() { result = "array content" }
}
private predicate storeStepNoChi(Node node1, Content f, PostUpdateNode node2) {
private predicate fieldStoreStepNoChi(Node node1, FieldContent f, PostUpdateNode node2) {
exists(StoreInstruction store, Class c |
store = node2.asInstruction() and
store.getSourceValue() = node1.asInstruction() and
getWrittenField(store, f.(FieldContent).getAField(), c) and
f.(FieldContent).hasOffset(c, _, _)
f.hasOffset(c, _, _)
)
}
private FieldAddressInstruction getFieldInstruction(Instruction instr) {
result = instr or
result = instr.(CopyValueInstruction).getUnary()
}
pragma[noinline]
private predicate getWrittenField(StoreInstruction store, Field f, Class c) {
private predicate getWrittenField(Instruction instr, Field f, Class c) {
exists(FieldAddressInstruction fa |
fa = store.getDestinationAddress() and
fa =
getFieldInstruction([instr.(StoreInstruction).getDestinationAddress(),
instr.(WriteSideEffectInstruction).getDestinationAddress()]) and
f = fa.getField() and
c = f.getDeclaringType()
)
}
private predicate storeStepChi(Node node1, Content f, PostUpdateNode node2) {
private predicate fieldStoreStepChi(Node node1, FieldContent f, PostUpdateNode node2) {
exists(StoreInstruction store, ChiInstruction chi |
node1.asInstruction() = store and
node2.asInstruction() = chi and
@@ -227,23 +236,59 @@ private predicate storeStepChi(Node node1, Content f, PostUpdateNode node2) {
c = chi.getResultType() and
exists(int startBit, int endBit |
chi.getUpdatedInterval(startBit, endBit) and
f.(FieldContent).hasOffset(c, startBit, endBit)
f.hasOffset(c, startBit, endBit)
)
or
getWrittenField(store, f.(FieldContent).getAField(), c) and
f.(FieldContent).hasOffset(c, _, _)
getWrittenField(store, f.getAField(), c) and
f.hasOffset(c, _, _)
)
)
}
private predicate arrayStoreStepChi(Node node1, ArrayContent a, PostUpdateNode node2) {
a = TArrayContent() and
exists(StoreInstruction store |
node1.asInstruction() = store and
(
// `x[i] = taint()`
// This matches the characteristic predicate in `ArrayStoreNode`.
store.getDestinationAddress() instanceof PointerAddInstruction
or
// `*p = taint()`
// This matches the characteristic predicate in `PointerStoreNode`.
store.getDestinationAddress().(CopyValueInstruction).getUnary() instanceof LoadInstruction
) and
// This `ChiInstruction` will always have a non-conflated result because both `ArrayStoreNode`
// and `PointerStoreNode` require it in their characteristic predicates.
node2.asInstruction().(ChiInstruction).getPartial() = store
)
}
/**
* Holds if data can flow from `node1` to `node2` via an assignment to `f`.
* Thus, `node2` references an object with a field `f` that contains the
* value of `node1`.
*/
predicate storeStep(Node node1, Content f, PostUpdateNode node2) {
storeStepNoChi(node1, f, node2) or
storeStepChi(node1, f, node2)
fieldStoreStepNoChi(node1, f, node2) or
fieldStoreStepChi(node1, f, node2) or
arrayStoreStepChi(node1, f, node2) or
fieldStoreStepAfterArraySuppression(node1, f, node2)
}
// This predicate pushes the correct `FieldContent` onto the access path when the
// `suppressArrayRead` predicate has popped off an `ArrayContent`.
private predicate fieldStoreStepAfterArraySuppression(
Node node1, FieldContent f, PostUpdateNode node2
) {
exists(BufferMayWriteSideEffectInstruction write, ChiInstruction chi, Class c |
not chi.isResultConflated() and
node1.asInstruction() = chi and
node2.asInstruction() = chi and
chi.getPartial() = write and
getWrittenField(write, f.getAField(), c) and
f.hasOffset(c, _, _)
)
}
bindingset[result, i]
@@ -263,7 +308,7 @@ private predicate getLoadedField(LoadInstruction load, Field f, Class c) {
* Thus, `node1` references an object with a field `f` whose value ends up in
* `node2`.
*/
predicate readStep(Node node1, Content f, Node node2) {
private predicate fieldReadStep(Node node1, FieldContent f, Node node2) {
exists(LoadInstruction load |
node2.asInstruction() = load and
node1.asInstruction() = load.getSourceValueOperand().getAnyDef() and
@@ -271,15 +316,114 @@ predicate readStep(Node node1, Content f, Node node2) {
c = load.getSourceValueOperand().getAnyDef().getResultType() and
exists(int startBit, int endBit |
load.getSourceValueOperand().getUsedInterval(unbindInt(startBit), unbindInt(endBit)) and
f.(FieldContent).hasOffset(c, startBit, endBit)
f.hasOffset(c, startBit, endBit)
)
or
getLoadedField(load, f.(FieldContent).getAField(), c) and
f.(FieldContent).hasOffset(c, _, _)
getLoadedField(load, f.getAField(), c) and
f.hasOffset(c, _, _)
)
)
}
/**
* When a store step happens in a function that looks like an array write such as:
* ```cpp
* void f(int* pa) {
* pa = source();
* }
* ```
* it can be a write to an array, but it can also happen that `f` is called as `f(&a.x)`. If that is
* the case, the `ArrayContent` that was written by the call to `f` should be popped off the access
* path, and a `FieldContent` containing `x` should be pushed instead.
* So this case pops `ArrayContent` off the access path, and the `fieldStoreStepAfterArraySuppression`
* predicate in `storeStep` ensures that we push the right `FieldContent` onto the access path.
*/
predicate suppressArrayRead(Node node1, ArrayContent a, Node node2) {
a = TArrayContent() and
exists(BufferMayWriteSideEffectInstruction write, ChiInstruction chi |
node1.asInstruction() = write and
node2.asInstruction() = chi and
chi.getPartial() = write and
getWrittenField(write, _, _)
)
}
private class ArrayToPointerConvertInstruction extends ConvertInstruction {
ArrayToPointerConvertInstruction() {
this.getUnary().getResultType() instanceof ArrayType and
this.getResultType() instanceof PointerType
}
}
private Instruction skipOneCopyValueInstructionRec(CopyValueInstruction copy) {
copy.getUnary() = result and not result instanceof CopyValueInstruction
or
result = skipOneCopyValueInstructionRec(copy.getUnary())
}
private Instruction skipCopyValueInstructions(Instruction instr) {
not result instanceof CopyValueInstruction and result = instr
or
result = skipOneCopyValueInstructionRec(instr)
}
private predicate arrayReadStep(Node node1, ArrayContent a, Node node2) {
a = TArrayContent() and
// Explicit dereferences such as `*p` or `p[i]` where `p` is a pointer or array.
exists(LoadInstruction load, Instruction address |
load.getSourceValueOperand().isDefinitionInexact() and
node1.asInstruction() = load.getSourceValueOperand().getAnyDef() and
load = node2.asInstruction() and
address = skipCopyValueInstructions(load.getSourceAddress()) and
(
address instanceof LoadInstruction or
address instanceof ArrayToPointerConvertInstruction or
address instanceof PointerOffsetInstruction
)
)
}
/**
* In cases such as:
* ```cpp
* void f(int* pa) {
* *pa = source();
* }
* ...
* int x;
* f(&x);
* use(x);
* ```
* the load on `x` in `use(x)` will exactly overlap with its definition (in this case the definition
* is a `BufferMayWriteSideEffect`). This predicate pops the `ArrayContent` (pushed by the store in `f`)
* from the access path.
*/
private predicate exactReadStep(Node node1, ArrayContent a, Node node2) {
a = TArrayContent() and
exists(BufferMayWriteSideEffectInstruction write, ChiInstruction chi |
not chi.isResultConflated() and
chi.getPartial() = write and
node1.asInstruction() = write and
node2.asInstruction() = chi and
// To distinquish this case from the `arrayReadStep` case we require that the entire variable was
// overwritten by the `BufferMayWriteSideEffectInstruction` (i.e., there is a load that reads the
// entire variable).
exists(LoadInstruction load | load.getSourceValue() = chi)
)
}
/**
* Holds if data can flow from `node1` to `node2` via a read of `f`.
* Thus, `node1` references an object with a field `f` whose value ends up in
* `node2`.
*/
predicate readStep(Node node1, Content f, Node node2) {
fieldReadStep(node1, f, node2) or
arrayReadStep(node1, f, node2) or
exactReadStep(node1, f, node2) or
suppressArrayRead(node1, f, node2)
}
/**
* Holds if values stored inside content `c` are cleared at node `n`.
*/

View File

@@ -389,6 +389,74 @@ private class ExplicitSingleFieldStoreQualifierNode extends PartialDefinitionNod
}
}
private FieldAddressInstruction getFieldInstruction(Instruction instr) {
result = instr or
result = instr.(CopyValueInstruction).getUnary()
}
/**
* The target of a `fieldStoreStepAfterArraySuppression` store step, which is used to convert
* an `ArrayContent` to a `FieldContent` when the `BufferMayWriteSideEffect` instruction stores
* into a field. See the QLDoc for `suppressArrayRead` for an example of where such a conversion
* is inserted.
*/
private class BufferMayWriteSideEffectFieldStoreQualifierNode extends PartialDefinitionNode {
override ChiInstruction instr;
BufferMayWriteSideEffectInstruction write;
FieldAddressInstruction field;
BufferMayWriteSideEffectFieldStoreQualifierNode() {
not instr.isResultConflated() and
instr.getPartial() = write and
field = getFieldInstruction(write.getDestinationAddress())
}
override Node getPreUpdateNode() { result.asOperand() = instr.getTotalOperand() }
override Expr getDefinedExpr() {
result = field.getObjectAddress().getUnconvertedResultExpression()
}
}
/**
* The `PostUpdateNode` that is the target of a `arrayStoreStepChi` store step. The overriden
* `ChiInstruction` corresponds to the instruction represented by `node2` in `arrayStoreStepChi`.
*/
private class ArrayStoreNode extends PartialDefinitionNode {
override ChiInstruction instr;
PointerAddInstruction add;
ArrayStoreNode() {
not instr.isResultConflated() and
exists(StoreInstruction store |
instr.getPartial() = store and
add = store.getDestinationAddress()
)
}
override Node getPreUpdateNode() { result.asOperand() = instr.getTotalOperand() }
override Expr getDefinedExpr() { result = add.getLeft().getUnconvertedResultExpression() }
}
/**
* The `PostUpdateNode` that is the target of a `arrayStoreStepChi` store step. The overriden
* `ChiInstruction` corresponds to the instruction represented by `node2` in `arrayStoreStepChi`.
*/
private class PointerStoreNode extends PostUpdateNode {
override ChiInstruction instr;
PointerStoreNode() {
not instr.isResultConflated() and
exists(StoreInstruction store |
instr.getPartial() = store and
store.getDestinationAddress().(CopyValueInstruction).getUnary() instanceof LoadInstruction
)
}
override Node getPreUpdateNode() { result.asOperand() = instr.getTotalOperand() }
}
/**
* A node that represents the value of a variable after a function call that
* may have changed the variable because it's passed by reference.
@@ -558,15 +626,16 @@ pragma[noinline]
private predicate getFieldSizeOfClass(Class c, Type type, int size) {
exists(Field f |
f.getDeclaringType() = c and
f.getType() = type and
f.getUnderlyingType() = type and
type.getSize() = size
)
}
private predicate isSingleFieldClass(Type type, Class cTo) {
exists(int size |
cTo.getSize() = size and
getFieldSizeOfClass(cTo, type, size)
private predicate isSingleFieldClass(Type type, Operand op) {
exists(int size, Class c |
c = op.getType().getUnderlyingType() and
c.getSize() = size and
getFieldSizeOfClass(c, type, size)
)
}
@@ -602,7 +671,7 @@ private predicate simpleOperandLocalFlowStep(Instruction iFrom, Operand opTo) {
exists(LoadInstruction load |
load.getSourceValueOperand() = opTo and
opTo.getAnyDef() = iFrom and
isSingleFieldClass(iFrom.getResultType(), opTo.getType())
isSingleFieldClass(iFrom.getResultType(), opTo)
)
}
@@ -677,7 +746,12 @@ private predicate modelFlow(Operand opFrom, Instruction iTo) {
iTo = outNode and
outNode = getSideEffectFor(call, index)
)
// TODO: add write side effects for qualifiers
or
exists(WriteSideEffectInstruction outNode |
modelOut.isQualifierObject() and
iTo = outNode and
outNode = getSideEffectFor(call, -1)
)
) and
(
exists(int index |
@@ -693,7 +767,12 @@ private predicate modelFlow(Operand opFrom, Instruction iTo) {
or
modelIn.isQualifierAddress() and
opFrom = call.getThisArgumentOperand()
// TODO: add read side effects for qualifiers
or
exists(ReadSideEffectInstruction read |
modelIn.isQualifierObject() and
read = getSideEffectFor(call, -1) and
opFrom = read.getSideEffectOperand()
)
)
)
}

View File

@@ -9,24 +9,31 @@ private import semmle.code.cpp.ir.dataflow.DataFlow
/**
* Gets the instruction that goes into `input` for `call`.
*/
Instruction callInput(CallInstruction call, FunctionInput input) {
DataFlow::Node callInput(CallInstruction call, FunctionInput input) {
// A positional argument
exists(int index |
result = call.getPositionalArgument(index) and
result.asInstruction() = call.getPositionalArgument(index) and
input.isParameter(index)
)
or
// A value pointed to by a positional argument
exists(ReadSideEffectInstruction read |
result = read and
result.asOperand() = read.getSideEffectOperand() and
read.getPrimaryInstruction() = call and
input.isParameterDeref(read.getIndex())
)
or
// The qualifier pointer
result = call.getThisArgument() and
result.asInstruction() = call.getThisArgument() and
input.isQualifierAddress()
//TODO: qualifier deref
or
// The qualifier object
exists(ReadSideEffectInstruction read |
result.asOperand() = read.getSideEffectOperand() and
read.getPrimaryInstruction() = call and
read.getIndex() = -1 and
input.isQualifierObject()
)
}
/**
@@ -43,5 +50,13 @@ Instruction callOutput(CallInstruction call, FunctionOutput output) {
effect.getPrimaryInstruction() = call and
output.isParameterDeref(effect.getIndex())
)
// TODO: qualifiers, return value dereference
or
// The side effect of a call on the qualifier object
exists(WriteSideEffectInstruction effect |
result = effect and
effect.getPrimaryInstruction() = call and
effect.getIndex() = -1 and
output.isQualifierObject()
)
// TODO: return value dereference
}

View File

@@ -19,8 +19,11 @@ predicate localTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
* local data flow steps. That is, `nodeFrom` and `nodeTo` are likely to represent
* different objects.
*/
cached
predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
localInstructionTaintStep(nodeFrom.asInstruction(), nodeTo.asInstruction())
or
modeledTaintStep(nodeFrom, nodeTo)
}
/**
@@ -49,8 +52,6 @@ private predicate localInstructionTaintStep(Instruction nodeFrom, Instruction no
or
nodeTo.(LoadInstruction).getSourceAddress() = nodeFrom
or
modeledInstructionTaintStep(nodeFrom, nodeTo)
or
// Flow through partial reads of arrays and unions
nodeTo.(LoadInstruction).getSourceValueOperand().getAnyDef() = nodeFrom and
not nodeFrom.isResultConflated() and
@@ -109,10 +110,17 @@ predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
* Holds if taint can flow from `instrIn` to `instrOut` through a call to a
* modeled function.
*/
predicate modeledInstructionTaintStep(Instruction instrIn, Instruction instrOut) {
predicate modeledTaintStep(DataFlow::Node nodeIn, DataFlow::Node nodeOut) {
exists(CallInstruction call, TaintFunction func, FunctionInput modelIn, FunctionOutput modelOut |
instrIn = callInput(call, modelIn) and
instrOut = callOutput(call, modelOut) and
(
nodeIn = callInput(call, modelIn)
or
exists(int n |
modelIn.isParameterDeref(n) and
nodeIn = callInput(call, any(InParameter inParam | inParam.getIndex() = n))
)
) and
nodeOut.asInstruction() = callOutput(call, modelOut) and
call.getStaticCallTarget() = func and
func.hasTaintFlow(modelIn, modelOut)
)
@@ -126,8 +134,8 @@ predicate modeledInstructionTaintStep(Instruction instrIn, Instruction instrOut)
CallInstruction call, Function func, FunctionInput modelIn, OutParameterDeref modelMidOut,
int indexMid, InParameter modelMidIn, OutReturnValue modelOut
|
instrIn = callInput(call, modelIn) and
instrOut = callOutput(call, modelOut) and
nodeIn = callInput(call, modelIn) and
nodeOut.asInstruction() = callOutput(call, modelOut) and
call.getStaticCallTarget() = func and
func.(TaintFunction).hasTaintFlow(modelIn, modelMidOut) and
func.(DataFlowFunction).hasDataFlow(modelMidIn, modelOut) and

View File

@@ -79,7 +79,8 @@ private PhiOperandBase phiOperand(
}
/**
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
* An operand of an `Instruction`. The operand represents a use of the result of one instruction
* (the defining instruction) in another instruction (the use instruction)
*/
class Operand extends TOperand {
/** Gets a textual representation of this element. */

View File

@@ -133,6 +133,12 @@ abstract class MemoryLocation extends TMemoryLocation {
predicate isAlwaysAllocatedOnStack() { none() }
}
/**
* Represents a set of `MemoryLocation`s that cannot overlap with
* `MemoryLocation`s outside of the set. The `VirtualVariable` will be
* represented by a `MemoryLocation` that totally overlaps all other
* `MemoryLocations` in the set.
*/
abstract class VirtualVariable extends MemoryLocation { }
abstract class AllocationMemoryLocation extends MemoryLocation {

View File

@@ -79,7 +79,8 @@ private PhiOperandBase phiOperand(
}
/**
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
* An operand of an `Instruction`. The operand represents a use of the result of one instruction
* (the defining instruction) in another instruction (the use instruction)
*/
class Operand extends TOperand {
/** Gets a textual representation of this element. */

View File

@@ -79,7 +79,8 @@ private PhiOperandBase phiOperand(
}
/**
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
* An operand of an `Instruction`. The operand represents a use of the result of one instruction
* (the defining instruction) in another instruction (the use instruction)
*/
class Operand extends TOperand {
/** Gets a textual representation of this element. */

View File

@@ -59,6 +59,12 @@ class MemoryLocation extends TMemoryLocation {
final string getUniqueId() { result = var.getUniqueId() }
}
/**
* Represents a set of `MemoryLocation`s that cannot overlap with
* `MemoryLocation`s outside of the set. The `VirtualVariable` will be
* represented by a `MemoryLocation` that totally overlaps all other
* `MemoryLocations` in the set.
*/
class VirtualVariable extends MemoryLocation { }
/** A virtual variable that groups all escaped memory within a function. */

View File

@@ -3,18 +3,33 @@ private newtype TOverlap =
TMustTotallyOverlap() or
TMustExactlyOverlap()
/**
* Represents a possible overlap between two memory ranges.
*/
abstract class Overlap extends TOverlap {
abstract string toString();
}
/**
* Represents a partial overlap between two memory ranges, which may or may not
* actually occur in practice.
*/
class MayPartiallyOverlap extends Overlap, TMayPartiallyOverlap {
final override string toString() { result = "MayPartiallyOverlap" }
}
/**
* Represents an overlap in which the first memory range is known to include all
* bits of the second memory range, but may be larger or have a different type.
*/
class MustTotallyOverlap extends Overlap, TMustTotallyOverlap {
final override string toString() { result = "MustTotallyOverlap" }
}
/**
* Represents an overlap between two memory ranges that have the same extent and
* the same type.
*/
class MustExactlyOverlap extends Overlap, TMustExactlyOverlap {
final override string toString() { result = "MustExactlyOverlap" }
}

View File

@@ -8,6 +8,7 @@
import cpp
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.DataFlow
import semmle.code.cpp.models.interfaces.Iterator
/**
* An instantiation of the `std::iterator_traits` template.
@@ -80,7 +81,7 @@ private FunctionInput getIteratorArgumentInput(Operator op, int index) {
/**
* A non-member prefix `operator*` function for an iterator type.
*/
class IteratorPointerDereferenceOperator extends Operator, TaintFunction {
class IteratorPointerDereferenceOperator extends Operator, TaintFunction, IteratorReferenceFunction {
FunctionInput iteratorInput;
IteratorPointerDereferenceOperator() {
@@ -169,7 +170,8 @@ class IteratorAssignArithmeticOperator extends Operator, DataFlowFunction, Taint
/**
* A prefix `operator*` member function for an iterator type.
*/
class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunction {
class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunction,
IteratorReferenceFunction {
IteratorPointerDereferenceMemberOperator() {
this.hasName("operator*") and
this.getDeclaringType() instanceof Iterator
@@ -260,7 +262,7 @@ class IteratorAssignArithmeticMemberOperator extends MemberFunction, DataFlowFun
/**
* An `operator[]` member function of an iterator class.
*/
class IteratorArrayMemberOperator extends MemberFunction, TaintFunction {
class IteratorArrayMemberOperator extends MemberFunction, TaintFunction, IteratorReferenceFunction {
IteratorArrayMemberOperator() {
this.hasName("operator[]") and
this.getDeclaringType() instanceof Iterator
@@ -271,3 +273,19 @@ class IteratorArrayMemberOperator extends MemberFunction, TaintFunction {
output.isReturnValue()
}
}
/**
* A `begin` or `end` member function, or a related member function, that
* returns an iterator.
*/
class BeginOrEndFunction extends MemberFunction, TaintFunction {
BeginOrEndFunction() {
this.hasName(["begin", "cbegin", "rbegin", "crbegin", "end", "cend", "rend", "crend"]) and
this.getType().getUnspecifiedType() instanceof Iterator
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
output.isReturnValue()
}
}

View File

@@ -21,7 +21,11 @@ class ConversionConstructorModel extends Constructor, TaintFunction {
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from the first constructor argument to the returned object
input.isParameter(0) and
output.isReturnValue() // TODO: this should be `isQualifierObject` by our current definitions, but that flow is not yet supported.
(
output.isReturnValue()
or
output.isQualifierObject()
)
}
}
@@ -32,7 +36,11 @@ class CopyConstructorModel extends CopyConstructor, DataFlowFunction {
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
// data flow from the first constructor argument to the returned object
input.isParameter(0) and
output.isReturnValue() // TODO: this should be `isQualifierObject` by our current definitions, but that flow is not yet supported.
(
output.isReturnValue()
or
output.isQualifierObject()
)
}
}
@@ -43,7 +51,11 @@ class MoveConstructorModel extends MoveConstructor, DataFlowFunction {
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
// data flow from the first constructor argument to the returned object
input.isParameter(0) and
output.isReturnValue() // TODO: this should be `isQualifierObject` by our current definitions, but that flow is not yet supported.
(
output.isReturnValue()
or
output.isQualifierObject()
)
}
}

View File

@@ -38,7 +38,11 @@ class StdSequenceContainerConstructor extends Constructor, TaintFunction {
input.isParameterDeref(getAValueTypeParameterIndex()) or
input.isParameter(getAnIteratorParameterIndex())
) and
output.isReturnValue() // TODO: this should be `isQualifierObject` by our current definitions, but that flow is not yet supported.
(
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
or
output.isQualifierObject()
)
}
}

View File

@@ -47,7 +47,11 @@ class StdStringConstructor extends Constructor, TaintFunction {
input.isParameterDeref(getAStringParameterIndex()) or
input.isParameter(getAnIteratorParameterIndex())
) and
output.isReturnValue() // TODO: this should be `isQualifierObject` by our current definitions, but that flow is not yet supported.
(
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
or
output.isQualifierObject()
)
}
}
@@ -212,23 +216,6 @@ class StdStringAssign extends TaintFunction {
}
}
/**
* The standard functions `std::string.begin` and `std::string.end` and their
* variants.
*/
class StdStringBeginEnd extends TaintFunction {
StdStringBeginEnd() {
this
.hasQualifiedName("std", "basic_string",
["begin", "cbegin", "rbegin", "crbegin", "end", "cend", "rend", "crend"])
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
output.isReturnValue()
}
}
/**
* The standard function `std::string.copy`.
*/
@@ -256,10 +243,13 @@ class StdStringSubstr extends TaintFunction {
}
/**
* The standard function `std::string.swap`.
* The standard functions `std::string.swap` and `std::stringstream::swap`.
*/
class StdStringSwap extends TaintFunction {
StdStringSwap() { this.hasQualifiedName("std", "basic_string", "swap") }
StdStringSwap() {
this.hasQualifiedName("std", "basic_string", "swap") or
this.hasQualifiedName("std", "basic_stringstream", "swap")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// str1.swap(str2)
@@ -288,6 +278,197 @@ class StdStringAt extends TaintFunction {
}
}
/**
* The `std::basic_istream` template class.
*/
class StdBasicIStream extends TemplateClass {
StdBasicIStream() { this.hasQualifiedName("std", "basic_istream") }
}
/**
* The `std::istream` function `operator>>` (defined as a member function).
*/
class StdIStreamIn extends DataFlowFunction, TaintFunction {
StdIStreamIn() { this.hasQualifiedName("std", "basic_istream", "operator>>") }
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
// returns reference to `*this`
input.isQualifierAddress() and
output.isReturnValue()
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to first parameter
input.isQualifierObject() and
output.isParameterDeref(0)
or
// reverse flow from returned reference to the qualifier
input.isReturnValueDeref() and
output.isQualifierObject()
}
}
/**
* The `std::istream` function `operator>>` (defined as a non-member function).
*/
class StdIStreamInNonMember extends DataFlowFunction, TaintFunction {
StdIStreamInNonMember() {
this.hasQualifiedName("std", "operator>>") and
this.getUnspecifiedType().(ReferenceType).getBaseType() =
any(StdBasicIStream s).getAnInstantiation()
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
// flow from first parameter to return value
input.isParameter(0) and
output.isReturnValue()
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from first parameter to second parameter
input.isParameterDeref(0) and
output.isParameterDeref(1)
or
// reverse flow from returned reference to the first parameter
input.isReturnValueDeref() and
output.isParameterDeref(0)
}
}
/**
* The `std::istream` functions `get` (without parameters) and `peek`.
*/
class StdIStreamGet extends TaintFunction {
StdIStreamGet() {
this.hasQualifiedName("std", "basic_istream", ["get", "peek"]) and
this.getNumberOfParameters() = 0
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to return value
input.isQualifierObject() and
output.isReturnValue()
}
}
/**
* The `std::istream` functions `get` (with parameters) and `read`.
*/
class StdIStreamRead extends DataFlowFunction, TaintFunction {
StdIStreamRead() {
this.hasQualifiedName("std", "basic_istream", ["get", "read"]) and
this.getNumberOfParameters() > 0
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
// returns reference to `*this`
input.isQualifierAddress() and
output.isReturnValue()
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to first parameter
input.isQualifierObject() and
output.isParameterDeref(0)
or
// reverse flow from returned reference to the qualifier
input.isReturnValueDeref() and
output.isQualifierObject()
}
}
/**
* The `std::istream` function `readsome`.
*/
class StdIStreamReadSome extends TaintFunction {
StdIStreamReadSome() { this.hasQualifiedName("std", "basic_istream", "readsome") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to first parameter
input.isQualifierObject() and
output.isParameterDeref(0)
}
}
/**
* The `std::istream` function `putback`.
*/
class StdIStreamPutBack extends DataFlowFunction, TaintFunction {
StdIStreamPutBack() { this.hasQualifiedName("std", "basic_istream", "putback") }
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
// returns reference to `*this`
input.isQualifierAddress() and
output.isReturnValue()
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from first parameter (value or pointer) to qualifier
input.isParameter(0) and
output.isQualifierObject()
or
input.isParameterDeref(0) and
output.isQualifierObject()
or
// flow from first parameter (value or pointer) to return value
input.isParameter(0) and
output.isReturnValueDeref()
or
input.isParameterDeref(0) and
output.isReturnValueDeref()
or
// reverse flow from returned reference to the qualifier
input.isReturnValueDeref() and
output.isQualifierObject()
}
}
/**
* The `std::istream` function `getline`.
*/
class StdIStreamGetLine extends DataFlowFunction, TaintFunction {
StdIStreamGetLine() { this.hasQualifiedName("std", "basic_istream", "getline") }
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
// returns reference to `*this`
input.isQualifierAddress() and
output.isReturnValue()
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to first parameter
input.isQualifierObject() and
output.isParameterDeref(0)
or
// reverse flow from returned reference to the qualifier
input.isReturnValueDeref() and
output.isQualifierObject()
}
}
/**
* The (non-member) function `std::getline`.
*/
class StdGetLine extends DataFlowFunction, TaintFunction {
StdGetLine() { this.hasQualifiedName("std", "getline") }
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
// flow from first parameter to return value
input.isParameter(0) and
output.isReturnValue()
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from first parameter to second parameter
input.isParameterDeref(0) and
output.isParameterDeref(1)
or
// reverse flow from returned reference to first parameter
input.isReturnValueDeref() and
output.isParameterDeref(0)
}
}
/**
* The `std::basic_ostream` template class.
*/
@@ -303,7 +484,7 @@ class StdOStreamOut extends DataFlowFunction, TaintFunction {
StdOStreamOut() { this.hasQualifiedName("std", "basic_ostream", ["operator<<", "put", "write"]) }
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to return value
// returns reference to `*this`
input.isQualifierAddress() and
output.isReturnValue()
}
@@ -379,7 +560,11 @@ class StdStringStreamConstructor extends Constructor, TaintFunction {
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from any parameter of string type to the returned object
input.isParameterDeref(getAStringParameterIndex()) and
output.isReturnValue() // TODO: this should be `isQualifierObject` by our current definitions, but that flow is not yet supported.
(
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
or
output.isQualifierObject()
)
}
}
@@ -399,3 +584,27 @@ class StdStringStreamStr extends TaintFunction {
output.isQualifierObject()
}
}
/**
* A `std::` stream function that does not require a model, except that it
* returns a reference to `*this` and thus could be used in a chain.
*/
class StdStreamFunction extends DataFlowFunction, TaintFunction {
StdStreamFunction() {
this.hasQualifiedName("std", "basic_istream", ["ignore", "unget", "seekg"]) or
this.hasQualifiedName("std", "basic_ostream", ["seekp", "flush"]) or
this.hasQualifiedName("std", "basic_ios", "copyfmt")
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
// returns reference to `*this`
input.isQualifierAddress() and
output.isReturnValue()
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// reverse flow from returned reference to the qualifier
input.isReturnValueDeref() and
output.isQualifierObject()
}
}

View File

@@ -0,0 +1,17 @@
/**
* Provides an abstract class for accurate modeling of flow through output
* iterators. To use this QL library, create a QL class extending
* `IteratorReferenceFunction` with a characteristic predicate that selects the
* function or set of functions you are modeling. Within that class, override
* the predicates provided by `AliasFunction` to match the flow within that
* function.
*/
import cpp
import semmle.code.cpp.models.Models
/**
* A function which takes an iterator argument and returns a reference that
* can be used to write to the iterator's underlying collection.
*/
abstract class IteratorReferenceFunction extends Function { }

View File

@@ -45,6 +45,7 @@
import cpp
private import RangeAnalysisUtils
private import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr
private import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisDefinition
import RangeSSA
import SimpleRangeAnalysisCached
private import NanAnalysis
@@ -335,6 +336,11 @@ private predicate defDependsOnDef(
or
// Phi nodes.
phiDependsOnDef(def, v, srcDef, srcVar)
or
// Extensions
exists(Expr expr | def.(SimpleRangeAnalysisDefinition).dependsOnExpr(v, expr) |
exprDependsOnDef(expr, srcDef, srcVar)
)
}
/**
@@ -492,6 +498,9 @@ private predicate analyzableDef(RangeSsaDefinition def, StackVariable v) {
v = def.getAVariable()
or
phiDependsOnDef(def, v, _, _)
or
// A modeled def for range analysis
def.(SimpleRangeAnalysisDefinition).hasRangeInformationFor(v)
}
/**
@@ -656,190 +665,192 @@ deprecated predicate positive_overflow(Expr expr) { exprMightOverflowPositively(
/** Only to be called by `getTruncatedLowerBounds`. */
private float getLowerBoundsImpl(Expr expr) {
exists(Expr operand, float operandLow, float positive |
effectivelyMultipliesByPositive(expr, operand, positive) and
operandLow = getFullyConvertedLowerBounds(operand) and
result = positive * operandLow
)
or
exists(Expr operand, float operandHigh, float negative |
effectivelyMultipliesByNegative(expr, operand, negative) and
operandHigh = getFullyConvertedUpperBounds(operand) and
result = negative * operandHigh
)
or
exists(MinExpr minExpr |
expr = minExpr and
// Return the union of the lower bounds from both children.
result = getFullyConvertedLowerBounds(minExpr.getAnOperand())
)
or
exists(MaxExpr maxExpr |
expr = maxExpr and
// Compute the cross product of the bounds from both children. We are
// using this mathematical property:
//
// max (minimum{X}, minimum{Y})
// = minimum { max(x,y) | x in X, y in Y }
exists(float x, float y |
x = getFullyConvertedLowerBounds(maxExpr.getLeftOperand()) and
y = getFullyConvertedLowerBounds(maxExpr.getRightOperand()) and
if x >= y then result = x else result = y
(
exists(Expr operand, float operandLow, float positive |
effectivelyMultipliesByPositive(expr, operand, positive) and
operandLow = getFullyConvertedLowerBounds(operand) and
result = positive * operandLow
)
)
or
// ConditionalExpr (true branch)
exists(ConditionalExpr condExpr |
expr = condExpr and
// Use `boolConversionUpperBound` to determine whether the condition
// might evaluate to `true`.
boolConversionUpperBound(condExpr.getCondition().getFullyConverted()) = 1 and
result = getFullyConvertedLowerBounds(condExpr.getThen())
)
or
// ConditionalExpr (false branch)
exists(ConditionalExpr condExpr |
expr = condExpr and
// Use `boolConversionLowerBound` to determine whether the condition
// might evaluate to `false`.
boolConversionLowerBound(condExpr.getCondition().getFullyConverted()) = 0 and
result = getFullyConvertedLowerBounds(condExpr.getElse())
)
or
exists(AddExpr addExpr, float xLow, float yLow |
expr = addExpr and
xLow = getFullyConvertedLowerBounds(addExpr.getLeftOperand()) and
yLow = getFullyConvertedLowerBounds(addExpr.getRightOperand()) and
result = addRoundingDown(xLow, yLow)
)
or
exists(SubExpr subExpr, float xLow, float yHigh |
expr = subExpr and
xLow = getFullyConvertedLowerBounds(subExpr.getLeftOperand()) and
yHigh = getFullyConvertedUpperBounds(subExpr.getRightOperand()) and
result = addRoundingDown(xLow, -yHigh)
)
or
exists(UnsignedMulExpr mulExpr, float xLow, float yLow |
expr = mulExpr and
xLow = getFullyConvertedLowerBounds(mulExpr.getLeftOperand()) and
yLow = getFullyConvertedLowerBounds(mulExpr.getRightOperand()) and
result = xLow * yLow
)
or
exists(AssignExpr assign |
expr = assign and
result = getFullyConvertedLowerBounds(assign.getRValue())
)
or
exists(AssignAddExpr addExpr, float xLow, float yLow |
expr = addExpr and
xLow = getFullyConvertedLowerBounds(addExpr.getLValue()) and
yLow = getFullyConvertedLowerBounds(addExpr.getRValue()) and
result = addRoundingDown(xLow, yLow)
)
or
exists(AssignSubExpr subExpr, float xLow, float yHigh |
expr = subExpr and
xLow = getFullyConvertedLowerBounds(subExpr.getLValue()) and
yHigh = getFullyConvertedUpperBounds(subExpr.getRValue()) and
result = addRoundingDown(xLow, -yHigh)
)
or
exists(UnsignedAssignMulExpr mulExpr, float xLow, float yLow |
expr = mulExpr and
xLow = getFullyConvertedLowerBounds(mulExpr.getLValue()) and
yLow = getFullyConvertedLowerBounds(mulExpr.getRValue()) and
result = xLow * yLow
)
or
exists(AssignMulByPositiveConstantExpr mulExpr, float xLow |
expr = mulExpr and
xLow = getFullyConvertedLowerBounds(mulExpr.getLValue()) and
result = xLow * mulExpr.getConstant()
)
or
exists(AssignMulByNegativeConstantExpr mulExpr, float xHigh |
expr = mulExpr and
xHigh = getFullyConvertedUpperBounds(mulExpr.getLValue()) and
result = xHigh * mulExpr.getConstant()
)
or
exists(PrefixIncrExpr incrExpr, float xLow |
expr = incrExpr and
xLow = getFullyConvertedLowerBounds(incrExpr.getOperand()) and
result = xLow + 1
)
or
exists(PrefixDecrExpr decrExpr, float xLow |
expr = decrExpr and
xLow = getFullyConvertedLowerBounds(decrExpr.getOperand()) and
result = addRoundingDownSmall(xLow, -1)
)
or
// `PostfixIncrExpr` and `PostfixDecrExpr` return the value of their
// operand. The incrementing/decrementing behavior is handled in
// `getDefLowerBoundsImpl`.
exists(PostfixIncrExpr incrExpr |
expr = incrExpr and
result = getFullyConvertedLowerBounds(incrExpr.getOperand())
)
or
exists(PostfixDecrExpr decrExpr |
expr = decrExpr and
result = getFullyConvertedLowerBounds(decrExpr.getOperand())
)
or
exists(RemExpr remExpr | expr = remExpr |
// If both inputs are positive then the lower bound is zero.
result = 0
or
// If either input could be negative then the output could be
// negative. If so, the lower bound of `x%y` is `-abs(y)`, which is
// equal to `min(-y,y)`.
exists(float childLB |
childLB = getFullyConvertedLowerBounds(remExpr.getAnOperand()) and
not childLB >= 0
|
result = getFullyConvertedLowerBounds(remExpr.getRightOperand())
or
exists(float rhsUB | rhsUB = getFullyConvertedUpperBounds(remExpr.getRightOperand()) |
result = -rhsUB
exists(Expr operand, float operandHigh, float negative |
effectivelyMultipliesByNegative(expr, operand, negative) and
operandHigh = getFullyConvertedUpperBounds(operand) and
result = negative * operandHigh
)
or
exists(MinExpr minExpr |
expr = minExpr and
// Return the union of the lower bounds from both children.
result = getFullyConvertedLowerBounds(minExpr.getAnOperand())
)
or
exists(MaxExpr maxExpr |
expr = maxExpr and
// Compute the cross product of the bounds from both children. We are
// using this mathematical property:
//
// max (minimum{X}, minimum{Y})
// = minimum { max(x,y) | x in X, y in Y }
exists(float x, float y |
x = getFullyConvertedLowerBounds(maxExpr.getLeftOperand()) and
y = getFullyConvertedLowerBounds(maxExpr.getRightOperand()) and
if x >= y then result = x else result = y
)
)
)
or
// If the conversion is to an arithmetic type then we just return the
// lower bound of the child. We do not need to handle truncation and
// overflow here, because that is done in `getTruncatedLowerBounds`.
// Conversions to `bool` need to be handled specially because they test
// whether the value of the expression is equal to 0.
exists(Conversion convExpr | expr = convExpr |
if convExpr.getUnspecifiedType() instanceof BoolType
then result = boolConversionLowerBound(convExpr.getExpr())
else result = getTruncatedLowerBounds(convExpr.getExpr())
)
or
// Use SSA to get the lower bounds for a variable use.
exists(RangeSsaDefinition def, StackVariable v | expr = def.getAUse(v) |
result = getDefLowerBounds(def, v) and
or
// ConditionalExpr (true branch)
exists(ConditionalExpr condExpr |
expr = condExpr and
// Use `boolConversionUpperBound` to determine whether the condition
// might evaluate to `true`.
boolConversionUpperBound(condExpr.getCondition().getFullyConverted()) = 1 and
result = getFullyConvertedLowerBounds(condExpr.getThen())
)
or
// ConditionalExpr (false branch)
exists(ConditionalExpr condExpr |
expr = condExpr and
// Use `boolConversionLowerBound` to determine whether the condition
// might evaluate to `false`.
boolConversionLowerBound(condExpr.getCondition().getFullyConverted()) = 0 and
result = getFullyConvertedLowerBounds(condExpr.getElse())
)
or
exists(AddExpr addExpr, float xLow, float yLow |
expr = addExpr and
xLow = getFullyConvertedLowerBounds(addExpr.getLeftOperand()) and
yLow = getFullyConvertedLowerBounds(addExpr.getRightOperand()) and
result = addRoundingDown(xLow, yLow)
)
or
exists(SubExpr subExpr, float xLow, float yHigh |
expr = subExpr and
xLow = getFullyConvertedLowerBounds(subExpr.getLeftOperand()) and
yHigh = getFullyConvertedUpperBounds(subExpr.getRightOperand()) and
result = addRoundingDown(xLow, -yHigh)
)
or
exists(UnsignedMulExpr mulExpr, float xLow, float yLow |
expr = mulExpr and
xLow = getFullyConvertedLowerBounds(mulExpr.getLeftOperand()) and
yLow = getFullyConvertedLowerBounds(mulExpr.getRightOperand()) and
result = xLow * yLow
)
or
exists(AssignExpr assign |
expr = assign and
result = getFullyConvertedLowerBounds(assign.getRValue())
)
or
exists(AssignAddExpr addExpr, float xLow, float yLow |
expr = addExpr and
xLow = getFullyConvertedLowerBounds(addExpr.getLValue()) and
yLow = getFullyConvertedLowerBounds(addExpr.getRValue()) and
result = addRoundingDown(xLow, yLow)
)
or
exists(AssignSubExpr subExpr, float xLow, float yHigh |
expr = subExpr and
xLow = getFullyConvertedLowerBounds(subExpr.getLValue()) and
yHigh = getFullyConvertedUpperBounds(subExpr.getRValue()) and
result = addRoundingDown(xLow, -yHigh)
)
or
exists(UnsignedAssignMulExpr mulExpr, float xLow, float yLow |
expr = mulExpr and
xLow = getFullyConvertedLowerBounds(mulExpr.getLValue()) and
yLow = getFullyConvertedLowerBounds(mulExpr.getRValue()) and
result = xLow * yLow
)
or
exists(AssignMulByPositiveConstantExpr mulExpr, float xLow |
expr = mulExpr and
xLow = getFullyConvertedLowerBounds(mulExpr.getLValue()) and
result = xLow * mulExpr.getConstant()
)
or
exists(AssignMulByNegativeConstantExpr mulExpr, float xHigh |
expr = mulExpr and
xHigh = getFullyConvertedUpperBounds(mulExpr.getLValue()) and
result = xHigh * mulExpr.getConstant()
)
or
exists(PrefixIncrExpr incrExpr, float xLow |
expr = incrExpr and
xLow = getFullyConvertedLowerBounds(incrExpr.getOperand()) and
result = xLow + 1
)
or
exists(PrefixDecrExpr decrExpr, float xLow |
expr = decrExpr and
xLow = getFullyConvertedLowerBounds(decrExpr.getOperand()) and
result = addRoundingDownSmall(xLow, -1)
)
or
// `PostfixIncrExpr` and `PostfixDecrExpr` return the value of their
// operand. The incrementing/decrementing behavior is handled in
// `getDefLowerBoundsImpl`.
exists(PostfixIncrExpr incrExpr |
expr = incrExpr and
result = getFullyConvertedLowerBounds(incrExpr.getOperand())
)
or
exists(PostfixDecrExpr decrExpr |
expr = decrExpr and
result = getFullyConvertedLowerBounds(decrExpr.getOperand())
)
or
exists(RemExpr remExpr | expr = remExpr |
// If both inputs are positive then the lower bound is zero.
result = 0
or
// If either input could be negative then the output could be
// negative. If so, the lower bound of `x%y` is `-abs(y)`, which is
// equal to `min(-y,y)`.
exists(float childLB |
childLB = getFullyConvertedLowerBounds(remExpr.getAnOperand()) and
not childLB >= 0
|
result = getFullyConvertedLowerBounds(remExpr.getRightOperand())
or
exists(float rhsUB | rhsUB = getFullyConvertedUpperBounds(remExpr.getRightOperand()) |
result = -rhsUB
)
)
)
or
// If the conversion is to an arithmetic type then we just return the
// lower bound of the child. We do not need to handle truncation and
// overflow here, because that is done in `getTruncatedLowerBounds`.
// Conversions to `bool` need to be handled specially because they test
// whether the value of the expression is equal to 0.
exists(Conversion convExpr | expr = convExpr |
if convExpr.getUnspecifiedType() instanceof BoolType
then result = boolConversionLowerBound(convExpr.getExpr())
else result = getTruncatedLowerBounds(convExpr.getExpr())
)
or
// Use SSA to get the lower bounds for a variable use.
exists(RangeSsaDefinition def, StackVariable v | expr = def.getAUse(v) |
result = getDefLowerBounds(def, v)
)
or
// unsigned `&` (tighter bounds may exist)
exists(UnsignedBitwiseAndExpr andExpr |
andExpr = expr and
result = 0.0
)
or
// `>>` by a constant
exists(RShiftExpr rsExpr, float left, int right |
rsExpr = expr and
left = getFullyConvertedLowerBounds(rsExpr.getLeftOperand()) and
right = getValue(rsExpr.getRightOperand().getFullyConverted()).toInt() and
result = safeFloor(left / 2.pow(right))
)
// Not explicitly modeled by a SimpleRangeAnalysisExpr
not expr instanceof SimpleRangeAnalysisExpr
)
or
// unsigned `&` (tighter bounds may exist)
exists(UnsignedBitwiseAndExpr andExpr |
andExpr = expr and
result = 0.0
)
or
// `>>` by a constant
exists(RShiftExpr rsExpr, float left, int right |
rsExpr = expr and
left = getFullyConvertedLowerBounds(rsExpr.getLeftOperand()) and
right = getValue(rsExpr.getRightOperand().getFullyConverted()).toInt() and
result = safeFloor(left / 2.pow(right))
)
) and
not expr instanceof SimpleRangeAnalysisExpr
or
// A modeled expression for range analysis
exists(SimpleRangeAnalysisExpr rangeAnalysisExpr |
@@ -850,190 +861,192 @@ private float getLowerBoundsImpl(Expr expr) {
/** Only to be called by `getTruncatedUpperBounds`. */
private float getUpperBoundsImpl(Expr expr) {
exists(Expr operand, float operandHigh, float positive |
effectivelyMultipliesByPositive(expr, operand, positive) and
operandHigh = getFullyConvertedUpperBounds(operand) and
result = positive * operandHigh
)
or
exists(Expr operand, float operandLow, float negative |
effectivelyMultipliesByNegative(expr, operand, negative) and
operandLow = getFullyConvertedLowerBounds(operand) and
result = negative * operandLow
)
or
exists(MaxExpr maxExpr |
expr = maxExpr and
// Return the union of the upper bounds from both children.
result = getFullyConvertedUpperBounds(maxExpr.getAnOperand())
)
or
exists(MinExpr minExpr |
expr = minExpr and
// Compute the cross product of the bounds from both children. We are
// using this mathematical property:
//
// min (maximum{X}, maximum{Y})
// = maximum { min(x,y) | x in X, y in Y }
exists(float x, float y |
x = getFullyConvertedUpperBounds(minExpr.getLeftOperand()) and
y = getFullyConvertedUpperBounds(minExpr.getRightOperand()) and
if x <= y then result = x else result = y
(
exists(Expr operand, float operandHigh, float positive |
effectivelyMultipliesByPositive(expr, operand, positive) and
operandHigh = getFullyConvertedUpperBounds(operand) and
result = positive * operandHigh
)
)
or
// ConditionalExpr (true branch)
exists(ConditionalExpr condExpr |
expr = condExpr and
// Use `boolConversionUpperBound` to determine whether the condition
// might evaluate to `true`.
boolConversionUpperBound(condExpr.getCondition().getFullyConverted()) = 1 and
result = getFullyConvertedUpperBounds(condExpr.getThen())
)
or
// ConditionalExpr (false branch)
exists(ConditionalExpr condExpr |
expr = condExpr and
// Use `boolConversionLowerBound` to determine whether the condition
// might evaluate to `false`.
boolConversionLowerBound(condExpr.getCondition().getFullyConverted()) = 0 and
result = getFullyConvertedUpperBounds(condExpr.getElse())
)
or
exists(AddExpr addExpr, float xHigh, float yHigh |
expr = addExpr and
xHigh = getFullyConvertedUpperBounds(addExpr.getLeftOperand()) and
yHigh = getFullyConvertedUpperBounds(addExpr.getRightOperand()) and
result = addRoundingUp(xHigh, yHigh)
)
or
exists(SubExpr subExpr, float xHigh, float yLow |
expr = subExpr and
xHigh = getFullyConvertedUpperBounds(subExpr.getLeftOperand()) and
yLow = getFullyConvertedLowerBounds(subExpr.getRightOperand()) and
result = addRoundingUp(xHigh, -yLow)
)
or
exists(UnsignedMulExpr mulExpr, float xHigh, float yHigh |
expr = mulExpr and
xHigh = getFullyConvertedUpperBounds(mulExpr.getLeftOperand()) and
yHigh = getFullyConvertedUpperBounds(mulExpr.getRightOperand()) and
result = xHigh * yHigh
)
or
exists(AssignExpr assign |
expr = assign and
result = getFullyConvertedUpperBounds(assign.getRValue())
)
or
exists(AssignAddExpr addExpr, float xHigh, float yHigh |
expr = addExpr and
xHigh = getFullyConvertedUpperBounds(addExpr.getLValue()) and
yHigh = getFullyConvertedUpperBounds(addExpr.getRValue()) and
result = addRoundingUp(xHigh, yHigh)
)
or
exists(AssignSubExpr subExpr, float xHigh, float yLow |
expr = subExpr and
xHigh = getFullyConvertedUpperBounds(subExpr.getLValue()) and
yLow = getFullyConvertedLowerBounds(subExpr.getRValue()) and
result = addRoundingUp(xHigh, -yLow)
)
or
exists(UnsignedAssignMulExpr mulExpr, float xHigh, float yHigh |
expr = mulExpr and
xHigh = getFullyConvertedUpperBounds(mulExpr.getLValue()) and
yHigh = getFullyConvertedUpperBounds(mulExpr.getRValue()) and
result = xHigh * yHigh
)
or
exists(AssignMulByPositiveConstantExpr mulExpr, float xHigh |
expr = mulExpr and
xHigh = getFullyConvertedUpperBounds(mulExpr.getLValue()) and
result = xHigh * mulExpr.getConstant()
)
or
exists(AssignMulByNegativeConstantExpr mulExpr, float xLow |
expr = mulExpr and
xLow = getFullyConvertedLowerBounds(mulExpr.getLValue()) and
result = xLow * mulExpr.getConstant()
)
or
exists(PrefixIncrExpr incrExpr, float xHigh |
expr = incrExpr and
xHigh = getFullyConvertedUpperBounds(incrExpr.getOperand()) and
result = addRoundingUpSmall(xHigh, 1)
)
or
exists(PrefixDecrExpr decrExpr, float xHigh |
expr = decrExpr and
xHigh = getFullyConvertedUpperBounds(decrExpr.getOperand()) and
result = xHigh - 1
)
or
// `PostfixIncrExpr` and `PostfixDecrExpr` return the value of their operand.
// The incrementing/decrementing behavior is handled in
// `getDefUpperBoundsImpl`.
exists(PostfixIncrExpr incrExpr |
expr = incrExpr and
result = getFullyConvertedUpperBounds(incrExpr.getOperand())
)
or
exists(PostfixDecrExpr decrExpr |
expr = decrExpr and
result = getFullyConvertedUpperBounds(decrExpr.getOperand())
)
or
exists(RemExpr remExpr, float rhsUB |
expr = remExpr and
rhsUB = getFullyConvertedUpperBounds(remExpr.getRightOperand())
|
result = rhsUB
or
// If the right hand side could be negative then we need to take its
// absolute value. Since `abs(x) = max(-x,x)` this is equivalent to
// adding `-rhsLB` to the set of upper bounds.
exists(float rhsLB |
rhsLB = getFullyConvertedLowerBounds(remExpr.getAnOperand()) and
not rhsLB >= 0
|
result = -rhsLB
exists(Expr operand, float operandLow, float negative |
effectivelyMultipliesByNegative(expr, operand, negative) and
operandLow = getFullyConvertedLowerBounds(operand) and
result = negative * operandLow
)
or
exists(MaxExpr maxExpr |
expr = maxExpr and
// Return the union of the upper bounds from both children.
result = getFullyConvertedUpperBounds(maxExpr.getAnOperand())
)
or
exists(MinExpr minExpr |
expr = minExpr and
// Compute the cross product of the bounds from both children. We are
// using this mathematical property:
//
// min (maximum{X}, maximum{Y})
// = maximum { min(x,y) | x in X, y in Y }
exists(float x, float y |
x = getFullyConvertedUpperBounds(minExpr.getLeftOperand()) and
y = getFullyConvertedUpperBounds(minExpr.getRightOperand()) and
if x <= y then result = x else result = y
)
)
or
// ConditionalExpr (true branch)
exists(ConditionalExpr condExpr |
expr = condExpr and
// Use `boolConversionUpperBound` to determine whether the condition
// might evaluate to `true`.
boolConversionUpperBound(condExpr.getCondition().getFullyConverted()) = 1 and
result = getFullyConvertedUpperBounds(condExpr.getThen())
)
or
// ConditionalExpr (false branch)
exists(ConditionalExpr condExpr |
expr = condExpr and
// Use `boolConversionLowerBound` to determine whether the condition
// might evaluate to `false`.
boolConversionLowerBound(condExpr.getCondition().getFullyConverted()) = 0 and
result = getFullyConvertedUpperBounds(condExpr.getElse())
)
or
exists(AddExpr addExpr, float xHigh, float yHigh |
expr = addExpr and
xHigh = getFullyConvertedUpperBounds(addExpr.getLeftOperand()) and
yHigh = getFullyConvertedUpperBounds(addExpr.getRightOperand()) and
result = addRoundingUp(xHigh, yHigh)
)
or
exists(SubExpr subExpr, float xHigh, float yLow |
expr = subExpr and
xHigh = getFullyConvertedUpperBounds(subExpr.getLeftOperand()) and
yLow = getFullyConvertedLowerBounds(subExpr.getRightOperand()) and
result = addRoundingUp(xHigh, -yLow)
)
or
exists(UnsignedMulExpr mulExpr, float xHigh, float yHigh |
expr = mulExpr and
xHigh = getFullyConvertedUpperBounds(mulExpr.getLeftOperand()) and
yHigh = getFullyConvertedUpperBounds(mulExpr.getRightOperand()) and
result = xHigh * yHigh
)
or
exists(AssignExpr assign |
expr = assign and
result = getFullyConvertedUpperBounds(assign.getRValue())
)
or
exists(AssignAddExpr addExpr, float xHigh, float yHigh |
expr = addExpr and
xHigh = getFullyConvertedUpperBounds(addExpr.getLValue()) and
yHigh = getFullyConvertedUpperBounds(addExpr.getRValue()) and
result = addRoundingUp(xHigh, yHigh)
)
or
exists(AssignSubExpr subExpr, float xHigh, float yLow |
expr = subExpr and
xHigh = getFullyConvertedUpperBounds(subExpr.getLValue()) and
yLow = getFullyConvertedLowerBounds(subExpr.getRValue()) and
result = addRoundingUp(xHigh, -yLow)
)
or
exists(UnsignedAssignMulExpr mulExpr, float xHigh, float yHigh |
expr = mulExpr and
xHigh = getFullyConvertedUpperBounds(mulExpr.getLValue()) and
yHigh = getFullyConvertedUpperBounds(mulExpr.getRValue()) and
result = xHigh * yHigh
)
or
exists(AssignMulByPositiveConstantExpr mulExpr, float xHigh |
expr = mulExpr and
xHigh = getFullyConvertedUpperBounds(mulExpr.getLValue()) and
result = xHigh * mulExpr.getConstant()
)
or
exists(AssignMulByNegativeConstantExpr mulExpr, float xLow |
expr = mulExpr and
xLow = getFullyConvertedLowerBounds(mulExpr.getLValue()) and
result = xLow * mulExpr.getConstant()
)
or
exists(PrefixIncrExpr incrExpr, float xHigh |
expr = incrExpr and
xHigh = getFullyConvertedUpperBounds(incrExpr.getOperand()) and
result = addRoundingUpSmall(xHigh, 1)
)
or
exists(PrefixDecrExpr decrExpr, float xHigh |
expr = decrExpr and
xHigh = getFullyConvertedUpperBounds(decrExpr.getOperand()) and
result = xHigh - 1
)
or
// `PostfixIncrExpr` and `PostfixDecrExpr` return the value of their operand.
// The incrementing/decrementing behavior is handled in
// `getDefUpperBoundsImpl`.
exists(PostfixIncrExpr incrExpr |
expr = incrExpr and
result = getFullyConvertedUpperBounds(incrExpr.getOperand())
)
or
exists(PostfixDecrExpr decrExpr |
expr = decrExpr and
result = getFullyConvertedUpperBounds(decrExpr.getOperand())
)
or
exists(RemExpr remExpr, float rhsUB |
expr = remExpr and
rhsUB = getFullyConvertedUpperBounds(remExpr.getRightOperand())
|
result = rhsUB
or
// If the right hand side could be negative then we need to take its
// absolute value. Since `abs(x) = max(-x,x)` this is equivalent to
// adding `-rhsLB` to the set of upper bounds.
exists(float rhsLB |
rhsLB = getFullyConvertedLowerBounds(remExpr.getAnOperand()) and
not rhsLB >= 0
|
result = -rhsLB
)
)
or
// If the conversion is to an arithmetic type then we just return the
// upper bound of the child. We do not need to handle truncation and
// overflow here, because that is done in `getTruncatedUpperBounds`.
// Conversions to `bool` need to be handled specially because they test
// whether the value of the expression is equal to 0.
exists(Conversion convExpr | expr = convExpr |
if convExpr.getUnspecifiedType() instanceof BoolType
then result = boolConversionUpperBound(convExpr.getExpr())
else result = getTruncatedUpperBounds(convExpr.getExpr())
)
or
// Use SSA to get the upper bounds for a variable use.
exists(RangeSsaDefinition def, StackVariable v | expr = def.getAUse(v) |
result = getDefUpperBounds(def, v)
)
or
// unsigned `&` (tighter bounds may exist)
exists(UnsignedBitwiseAndExpr andExpr, float left, float right |
andExpr = expr and
left = getFullyConvertedUpperBounds(andExpr.getLeftOperand()) and
right = getFullyConvertedUpperBounds(andExpr.getRightOperand()) and
result = left.minimum(right)
)
or
// `>>` by a constant
exists(RShiftExpr rsExpr, float left, int right |
rsExpr = expr and
left = getFullyConvertedUpperBounds(rsExpr.getLeftOperand()) and
right = getValue(rsExpr.getRightOperand().getFullyConverted()).toInt() and
result = safeFloor(left / 2.pow(right))
)
)
or
// If the conversion is to an arithmetic type then we just return the
// upper bound of the child. We do not need to handle truncation and
// overflow here, because that is done in `getTruncatedUpperBounds`.
// Conversions to `bool` need to be handled specially because they test
// whether the value of the expression is equal to 0.
exists(Conversion convExpr | expr = convExpr |
if convExpr.getUnspecifiedType() instanceof BoolType
then result = boolConversionUpperBound(convExpr.getExpr())
else result = getTruncatedUpperBounds(convExpr.getExpr())
)
or
// Use SSA to get the upper bounds for a variable use.
exists(RangeSsaDefinition def, StackVariable v | expr = def.getAUse(v) |
result = getDefUpperBounds(def, v) and
// Not explicitly modeled by a SimpleRangeAnalysisExpr
not expr instanceof SimpleRangeAnalysisExpr
)
or
// unsigned `&` (tighter bounds may exist)
exists(UnsignedBitwiseAndExpr andExpr, float left, float right |
andExpr = expr and
left = getFullyConvertedUpperBounds(andExpr.getLeftOperand()) and
right = getFullyConvertedUpperBounds(andExpr.getRightOperand()) and
result = left.minimum(right)
)
or
// `>>` by a constant
exists(RShiftExpr rsExpr, float left, int right |
rsExpr = expr and
left = getFullyConvertedUpperBounds(rsExpr.getLeftOperand()) and
right = getValue(rsExpr.getRightOperand().getFullyConverted()).toInt() and
result = safeFloor(left / 2.pow(right))
)
) and
not expr instanceof SimpleRangeAnalysisExpr
or
// A modeled expression for range analysis
exists(SimpleRangeAnalysisExpr rangeAnalysisExpr |
@@ -1211,6 +1224,9 @@ private float getDefLowerBoundsImpl(RangeSsaDefinition def, StackVariable v) {
// Phi nodes.
result = getPhiLowerBounds(v, def)
or
// A modeled def for range analysis
result = def.(SimpleRangeAnalysisDefinition).getLowerBounds(v)
or
// Unanalyzable definitions.
unanalyzableDefBounds(def, v, result, _)
}
@@ -1244,6 +1260,9 @@ private float getDefUpperBoundsImpl(RangeSsaDefinition def, StackVariable v) {
// Phi nodes.
result = getPhiUpperBounds(v, def)
or
// A modeled def for range analysis
result = def.(SimpleRangeAnalysisDefinition).getUpperBounds(v)
or
// Unanalyzable definitions.
unanalyzableDefBounds(def, v, _, result)
}

View File

@@ -0,0 +1,9 @@
void test_overridability_sub(int x) {
int zero = x - x;
zero; // 0
int nonzero = x - (unsigned char)x;
nonzero; // full range
}

View File

@@ -0,0 +1,6 @@
| extended.cpp:4:14:4:14 | x | -2.147483648E9 | 2.147483647E9 |
| extended.cpp:4:18:4:18 | x | -2.147483648E9 | 2.147483647E9 |
| extended.cpp:5:3:5:6 | zero | 0.0 | 0.0 |
| extended.cpp:7:17:7:17 | x | -2.147483648E9 | 2.147483647E9 |
| extended.cpp:7:36:7:36 | x | -2.147483648E9 | 2.147483647E9 |
| extended.cpp:8:3:8:9 | nonzero | -2.147483648E9 | 2.147483647E9 |

View File

@@ -0,0 +1,7 @@
import experimental.semmle.code.cpp.rangeanalysis.ExtendedRangeAnalysis
from VariableAccess expr, float lower, float upper
where
lower = lowerBound(expr) and
upper = upperBound(expr)
select expr, lower, upper

View File

@@ -7,3 +7,13 @@ int test_extensibility_add(int x) {
return result; // 90 .. 110
}
}
int test_overridability_sub(int x) {
int result = x - (unsigned char)x; // Returns 0 due to custom modeling for this test being deliberately wrong
return result; // 0
}
void test_parameter_override(int magic_name_at_most_10, int magic_name_at_most_20) {
magic_name_at_most_10;
magic_name_at_most_20;
}

View File

@@ -2,3 +2,8 @@
| extensibility.c:5:19:5:19 | x | -10.0 | 2.147483647E9 |
| extensibility.c:6:38:6:38 | x | -10.0 | 10.0 |
| extensibility.c:7:12:7:17 | result | 90.0 | 110.0 |
| extensibility.c:12:16:12:16 | x | -2.147483648E9 | 2.147483647E9 |
| extensibility.c:12:35:12:35 | x | -2.147483648E9 | 2.147483647E9 |
| extensibility.c:13:10:13:15 | result | 0.0 | 0.0 |
| extensibility.c:17:3:17:23 | magic_name_at_most_10 | -2.147483648E9 | 10.0 |
| extensibility.c:18:3:18:23 | magic_name_at_most_20 | -2.147483648E9 | 20.0 |

View File

@@ -1,5 +1,7 @@
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr
import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisDefinition
class CustomAddFunctionCall extends SimpleRangeAnalysisExpr, FunctionCall {
CustomAddFunctionCall() { this.getTarget().hasGlobalName("custom_add_function") }
@@ -25,6 +27,52 @@ class CustomAddFunctionCall extends SimpleRangeAnalysisExpr, FunctionCall {
override predicate dependsOnChild(Expr child) { child = this.getAnArgument() }
}
class SelfSub extends SimpleRangeAnalysisExpr, SubExpr {
SelfSub() {
getLeftOperand().(VariableAccess).getTarget() = getRightOperand().(VariableAccess).getTarget()
}
override float getLowerBounds() { result = 0 }
override float getUpperBounds() { result = 0 }
override predicate dependsOnChild(Expr child) { child = this.getAnOperand() }
}
/**
* A definition for test purposes of a parameter `p` that starts with a
* special prefix. This class is written to exploit how QL behaves when class
* fields are not functionally determined by `this`. When multiple parameters
* of the same function have the special prefix, there is still only one
* instance of this class.
*/
class MagicParameterName extends SimpleRangeAnalysisDefinition {
Parameter p;
float value;
MagicParameterName() {
this.definedByParameter(p) and
value = p.getName().regexpCapture("magic_name_at_most_(\\d+)", 1).toFloat()
}
override predicate hasRangeInformationFor(StackVariable v) { v = p }
override predicate dependsOnExpr(StackVariable v, Expr e) {
// No dependencies. This sample class yields constant values.
none()
}
override float getLowerBounds(StackVariable var) {
var = p and
result = typeLowerBound(p.getUnspecifiedType())
}
override float getUpperBounds(StackVariable var) {
var = p and
result = value
}
}
from VariableAccess expr, float lower, float upper
where
lower = lowerBound(expr) and

View File

@@ -112,51 +112,28 @@
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:140:11:140:16 | call to getenv |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:140:11:140:26 | (int)... |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:140:11:140:26 | access to array |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:143:23:143:24 | pp |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:144:8:144:9 | pp |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:150:13:150:14 | & ... |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:154:11:154:15 | p#0 |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:162:50:162:50 | p |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:164:8:164:8 | p |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:165:8:165:9 | & ... |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:166:10:166:10 | x |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:187:8:187:9 | pp |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | shared.h:6:15:6:23 | sinkparam |
| defaulttainttracking.cpp:157:9:157:14 | call to getenv | defaulttainttracking.cpp:157:9:157:14 | call to getenv |
| defaulttainttracking.cpp:157:9:157:14 | call to getenv | defaulttainttracking.cpp:157:9:157:24 | (int)... |
| defaulttainttracking.cpp:157:9:157:14 | call to getenv | defaulttainttracking.cpp:157:9:157:24 | access to array |
| defaulttainttracking.cpp:157:9:157:14 | call to getenv | defaulttainttracking.cpp:159:10:159:10 | x |
| defaulttainttracking.cpp:157:9:157:14 | call to getenv | shared.h:6:15:6:23 | sinkparam |
| defaulttainttracking.cpp:170:11:170:16 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 |
| defaulttainttracking.cpp:170:11:170:16 | call to getenv | defaulttainttracking.cpp:170:11:170:16 | call to getenv |
| defaulttainttracking.cpp:170:11:170:16 | call to getenv | defaulttainttracking.cpp:170:11:170:26 | (int)... |
| defaulttainttracking.cpp:170:11:170:16 | call to getenv | defaulttainttracking.cpp:170:11:170:26 | access to array |
| defaulttainttracking.cpp:170:11:170:16 | call to getenv | defaulttainttracking.cpp:171:8:171:9 | pp |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:154:11:154:15 | p#0 |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:175:33:175:34 | pp |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:176:8:176:9 | pp |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:177:8:177:10 | * ... |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:177:9:177:10 | pp |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:181:11:181:16 | call to getenv |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:181:11:181:26 | (int)... |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:181:11:181:26 | access to array |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:182:23:182:24 | pp |
| defaulttainttracking.cpp:195:11:195:16 | call to getenv | defaulttainttracking.cpp:195:11:195:16 | call to getenv |
| defaulttainttracking.cpp:195:11:195:16 | call to getenv | defaulttainttracking.cpp:195:11:195:26 | (int)... |
| defaulttainttracking.cpp:195:11:195:16 | call to getenv | defaulttainttracking.cpp:195:11:195:26 | access to array |
| defaulttainttracking.cpp:201:13:201:18 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 |
| defaulttainttracking.cpp:201:13:201:18 | call to getenv | defaulttainttracking.cpp:201:13:201:18 | call to getenv |
| defaulttainttracking.cpp:201:13:201:18 | call to getenv | defaulttainttracking.cpp:201:13:201:28 | (int)... |
| defaulttainttracking.cpp:201:13:201:18 | call to getenv | defaulttainttracking.cpp:201:13:201:28 | access to array |
| defaulttainttracking.cpp:201:13:201:18 | call to getenv | defaulttainttracking.cpp:203:8:203:9 | pp |
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 |
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:208:27:208:32 | call to getenv |
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:208:27:208:42 | (int)... |
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:208:27:208:42 | access to array |
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:209:8:209:9 | pp |
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:210:8:210:23 | ... + ... |
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:28:24:28:27 | call to atoi |
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:28:29:28:34 | call to getenv |
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:28:29:28:45 | (const char *)... |

View File

@@ -26,39 +26,16 @@
| defaulttainttracking.cpp:133:9:133:14 | call to getenv | defaulttainttracking.cpp:134:10:134:10 | x | IR only |
| defaulttainttracking.cpp:133:9:133:14 | call to getenv | shared.h:6:15:6:23 | sinkparam | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:140:7:140:7 | x | AST only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:143:23:143:24 | pp | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:144:8:144:9 | pp | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:150:13:150:14 | & ... | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:154:11:154:15 | p#0 | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:162:50:162:50 | p | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:164:8:164:8 | p | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:165:8:165:9 | & ... | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:166:10:166:10 | x | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:187:8:187:9 | pp | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | shared.h:6:15:6:23 | sinkparam | IR only |
| defaulttainttracking.cpp:157:9:157:14 | call to getenv | defaulttainttracking.cpp:157:5:157:5 | x | AST only |
| defaulttainttracking.cpp:157:9:157:14 | call to getenv | defaulttainttracking.cpp:159:10:159:10 | x | IR only |
| defaulttainttracking.cpp:157:9:157:14 | call to getenv | shared.h:6:15:6:23 | sinkparam | IR only |
| defaulttainttracking.cpp:170:11:170:16 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 | IR only |
| defaulttainttracking.cpp:170:11:170:16 | call to getenv | defaulttainttracking.cpp:170:7:170:7 | x | AST only |
| defaulttainttracking.cpp:170:11:170:16 | call to getenv | defaulttainttracking.cpp:171:8:171:9 | pp | IR only |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 | IR only |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:154:11:154:15 | p#0 | IR only |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:175:33:175:34 | pp | IR only |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:176:8:176:9 | pp | IR only |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:177:8:177:10 | * ... | IR only |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:177:9:177:10 | pp | IR only |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:181:7:181:7 | x | AST only |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:182:23:182:24 | pp | IR only |
| defaulttainttracking.cpp:195:11:195:16 | call to getenv | defaulttainttracking.cpp:195:7:195:7 | x | AST only |
| defaulttainttracking.cpp:201:13:201:18 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 | IR only |
| defaulttainttracking.cpp:201:13:201:18 | call to getenv | defaulttainttracking.cpp:201:9:201:9 | x | AST only |
| defaulttainttracking.cpp:201:13:201:18 | call to getenv | defaulttainttracking.cpp:203:8:203:9 | pp | IR only |
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 | IR only |
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:208:23:208:23 | x | AST only |
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:209:8:209:9 | pp | IR only |
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:210:8:210:23 | ... + ... | IR only |
| globals.cpp:13:15:13:20 | call to getenv | globals.cpp:13:5:13:11 | global1 | AST only |
| globals.cpp:23:15:23:20 | call to getenv | globals.cpp:23:5:23:11 | global2 | AST only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:43:78:43:104 | p#0 | IR only |

View File

@@ -48,6 +48,6 @@ void following_pointers(
int stackArray[2] = { source(), source() };
stackArray[0] = source();
sink(stackArray); // no flow
sink(stackArray); // flow
}

View File

@@ -13,6 +13,7 @@
| example.c:24:13:24:18 | coords [post update] | example.c:26:19:26:24 | coords |
| example.c:24:13:24:30 | ... = ... | example.c:24:2:24:30 | ... = ... |
| example.c:24:13:24:30 | ... = ... | example.c:24:20:24:20 | y [post update] |
| example.c:24:20:24:20 | y | example.c:24:13:24:30 | ... = ... |
| example.c:24:24:24:30 | ... + ... | example.c:24:13:24:30 | ... = ... |
| example.c:26:2:26:25 | ... = ... | example.c:26:9:26:9 | x [post update] |
| example.c:26:13:26:16 | call to getX | example.c:26:2:26:25 | ... = ... |

View File

@@ -56,13 +56,13 @@ namespace withoutFields {
sink(x1); // flow [FALSE POSITIVE from uninitialized]
notAssign(x2, source());
sink(x2); // no flow [FALSE POSITIVE from uninitialized]
sink(x2); // no flow [FALSE POSITIVE from uninitialized, FALSE POSITIVE by IR]
sourceToParamWrapper(x3);
sink(x3); // flow [FALSE POSITIVE from uninitialized]
notSource(x4);
sink(x4); // no flow [FALSE POSITIVE from uninitialized]
sink(x4); // no flow [FALSE POSITIVE from uninitialized, FALSE POSITIVE by IR]
}
}

View File

@@ -428,7 +428,7 @@ void intPointerSourceCaller2() {
int local[1];
intPointerSource(local);
sink(local); // tainted
sink(*local); // clean
sink(*local); // tainted
}
void intArraySourceCaller() {
@@ -441,7 +441,7 @@ void intArraySourceCaller2() {
int local[2];
intArraySource(local, 2);
sink(local); // tainted
sink(*local); // clean
sink(*local); // tainted
}
///////////////////////////////////////////////////////////////////////////////
@@ -468,5 +468,5 @@ void intOutparamSource(int *p) {
void viaOutparam() {
int x = 0;
intOutparamSource(&x);
sink(x); // tainted [FALSE NEGATIVE]
sink(x); // tainted
}

View File

@@ -16,6 +16,7 @@
| clang.cpp:30:27:30:34 | call to getFirst | clang.cpp:28:27:28:32 | call to source |
| clang.cpp:37:10:37:11 | m2 | clang.cpp:34:32:34:37 | call to source |
| clang.cpp:45:17:45:18 | m2 | clang.cpp:43:35:43:40 | call to source |
| clang.cpp:51:8:51:17 | stackArray | clang.cpp:50:19:50:24 | call to source |
| dispatch.cpp:11:38:11:38 | x | dispatch.cpp:37:19:37:24 | call to source |
| dispatch.cpp:11:38:11:38 | x | dispatch.cpp:45:18:45:23 | call to source |
| dispatch.cpp:35:16:35:25 | call to notSource1 | dispatch.cpp:9:37:9:42 | call to source |
@@ -79,12 +80,17 @@
| test.cpp:424:8:424:12 | local | test.cpp:423:20:423:25 | ref arg & ... |
| test.cpp:430:8:430:12 | local | test.cpp:428:7:428:11 | local |
| test.cpp:430:8:430:12 | local | test.cpp:429:20:429:24 | ref arg local |
| test.cpp:431:8:431:13 | * ... | test.cpp:428:7:428:11 | local |
| test.cpp:431:8:431:13 | * ... | test.cpp:429:20:429:24 | ref arg local |
| test.cpp:437:8:437:12 | local | test.cpp:435:7:435:11 | local |
| test.cpp:437:8:437:12 | local | test.cpp:436:18:436:23 | ref arg & ... |
| test.cpp:443:8:443:12 | local | test.cpp:441:7:441:11 | local |
| test.cpp:443:8:443:12 | local | test.cpp:442:18:442:22 | ref arg local |
| test.cpp:444:8:444:13 | * ... | test.cpp:441:7:441:11 | local |
| test.cpp:444:8:444:13 | * ... | test.cpp:442:18:442:22 | ref arg local |
| test.cpp:450:9:450:22 | (statement expression) | test.cpp:449:26:449:32 | source1 |
| test.cpp:461:8:461:12 | local | test.cpp:449:26:449:32 | source1 |
| test.cpp:471:8:471:8 | x | test.cpp:465:8:465:13 | call to source |
| true_upon_entry.cpp:21:8:21:8 | x | true_upon_entry.cpp:17:11:17:16 | call to source |
| true_upon_entry.cpp:29:8:29:8 | x | true_upon_entry.cpp:27:9:27:14 | call to source |
| true_upon_entry.cpp:39:8:39:8 | x | true_upon_entry.cpp:33:11:33:16 | call to source |

View File

@@ -2,6 +2,7 @@
| BarrierGuard.cpp:60:11:60:16 | BarrierGuard.cpp:62:14:62:14 | AST only |
| clang.cpp:12:9:12:20 | clang.cpp:22:8:22:20 | AST only |
| clang.cpp:39:42:39:47 | clang.cpp:41:18:41:19 | IR only |
| clang.cpp:50:19:50:24 | clang.cpp:51:8:51:17 | AST only |
| dispatch.cpp:16:37:16:42 | dispatch.cpp:32:16:32:24 | IR only |
| dispatch.cpp:16:37:16:42 | dispatch.cpp:40:15:40:23 | IR only |
| dispatch.cpp:22:37:22:42 | dispatch.cpp:31:16:31:24 | IR only |
@@ -19,13 +20,12 @@
| globals.cpp:13:23:13:28 | globals.cpp:12:10:12:24 | IR only |
| globals.cpp:23:23:23:28 | globals.cpp:19:10:19:24 | IR only |
| lambdas.cpp:8:10:8:15 | lambdas.cpp:21:3:21:6 | AST only |
| lambdas.cpp:43:7:43:12 | lambdas.cpp:46:7:46:7 | AST only |
| ref.cpp:29:11:29:16 | ref.cpp:62:10:62:11 | AST only |
| ref.cpp:44:11:44:16 | ref.cpp:65:10:65:11 | IR only |
| ref.cpp:53:9:53:10 | ref.cpp:56:10:56:11 | AST only |
| ref.cpp:53:13:53:14 | ref.cpp:59:10:59:11 | AST only |
| ref.cpp:53:17:53:18 | ref.cpp:62:10:62:11 | AST only |
| ref.cpp:53:21:53:22 | ref.cpp:65:10:65:11 | AST only |
| ref.cpp:55:23:55:28 | ref.cpp:56:10:56:11 | AST only |
| ref.cpp:58:19:58:24 | ref.cpp:59:10:59:11 | IR only |
| test.cpp:75:7:75:8 | test.cpp:76:8:76:9 | AST only |
| test.cpp:83:7:83:8 | test.cpp:84:8:84:18 | AST only |
| test.cpp:83:7:83:8 | test.cpp:86:8:86:9 | AST only |
@@ -41,11 +41,15 @@
| test.cpp:422:7:422:11 | test.cpp:424:8:424:12 | AST only |
| test.cpp:423:20:423:25 | test.cpp:424:8:424:12 | AST only |
| test.cpp:428:7:428:11 | test.cpp:430:8:430:12 | AST only |
| test.cpp:428:7:428:11 | test.cpp:431:8:431:13 | AST only |
| test.cpp:429:20:429:24 | test.cpp:430:8:430:12 | AST only |
| test.cpp:429:20:429:24 | test.cpp:431:8:431:13 | AST only |
| test.cpp:435:7:435:11 | test.cpp:437:8:437:12 | AST only |
| test.cpp:436:18:436:23 | test.cpp:437:8:437:12 | AST only |
| test.cpp:441:7:441:11 | test.cpp:443:8:443:12 | AST only |
| test.cpp:441:7:441:11 | test.cpp:444:8:444:13 | AST only |
| test.cpp:442:18:442:22 | test.cpp:443:8:443:12 | AST only |
| test.cpp:442:18:442:22 | test.cpp:444:8:444:13 | AST only |
| true_upon_entry.cpp:9:11:9:16 | true_upon_entry.cpp:13:8:13:8 | IR only |
| true_upon_entry.cpp:62:11:62:16 | true_upon_entry.cpp:66:8:66:8 | IR only |
| true_upon_entry.cpp:98:11:98:16 | true_upon_entry.cpp:105:8:105:8 | IR only |

View File

@@ -44,6 +44,11 @@
| lambdas.cpp:29:3:29:6 | t | lambdas.cpp:8:10:8:15 | call to source |
| lambdas.cpp:35:8:35:8 | a | lambdas.cpp:8:10:8:15 | call to source |
| lambdas.cpp:41:8:41:8 | (reference dereference) | lambdas.cpp:8:10:8:15 | call to source |
| lambdas.cpp:46:7:46:7 | w | lambdas.cpp:43:7:43:12 | call to source |
| ref.cpp:56:10:56:11 | x1 | ref.cpp:55:23:55:28 | call to source |
| ref.cpp:59:10:59:11 | x2 | ref.cpp:58:19:58:24 | call to source |
| ref.cpp:62:10:62:11 | x3 | ref.cpp:29:11:29:16 | call to source |
| ref.cpp:65:10:65:11 | x4 | ref.cpp:44:11:44:16 | call to source |
| ref.cpp:123:13:123:15 | val | ref.cpp:122:23:122:28 | call to source |
| ref.cpp:126:13:126:15 | val | ref.cpp:125:19:125:24 | call to source |
| ref.cpp:129:13:129:15 | val | ref.cpp:94:15:94:20 | call to source |
@@ -77,6 +82,7 @@
| test.cpp:394:10:394:12 | tmp | test.cpp:388:53:388:59 | source1 |
| test.cpp:450:9:450:22 | (statement expression) | test.cpp:449:26:449:32 | source1 |
| test.cpp:461:8:461:12 | local | test.cpp:449:26:449:32 | source1 |
| test.cpp:471:8:471:8 | x | test.cpp:465:8:465:13 | call to source |
| true_upon_entry.cpp:13:8:13:8 | x | true_upon_entry.cpp:9:11:9:16 | call to source |
| true_upon_entry.cpp:21:8:21:8 | x | true_upon_entry.cpp:17:11:17:16 | call to source |
| true_upon_entry.cpp:29:8:29:8 | x | true_upon_entry.cpp:27:9:27:14 | call to source |

View File

@@ -100,4 +100,108 @@ void addressOfField() {
S s_copy = s;
int* px = &s_copy.m1;
sink(*px); // $f-:ast $ir
}
void taint_a_ptr(int* pa) {
*pa = user_input();
}
void test_field_conflation_array_content() {
S s;
taint_a_ptr(&s.m1);
sink(s.m2);
}
struct S_with_pointer {
int m1, m2;
int* data;
};
void pointer_deref(int* xs) {
taint_a_ptr(xs);
sink(xs[0]); // $f-:ast $ir
}
void pointer_deref_sub(int* xs) {
taint_a_ptr(xs - 2);
sink(*(xs - 2)); // $f-:ast $ir
}
void pointer_many_addrof_and_deref(int* xs) {
taint_a_ptr(xs);
sink(*&*&*xs); // $f-:ast $ir
}
void pointer_unary_plus(int* xs) {
taint_a_ptr(+xs);
sink(*+xs); // $f-:ast $ir
}
void pointer_member_index(S_with_pointer s) {
taint_a_ptr(s.data);
// `s.data` is points to all-aliased-memory
sink(s.data[0]); // $f-:ast,ir
}
void member_array_different_field(S_with_pointer* s) {
taint_a_ptr(&s[0].m1);
sink(s[0].m2);
}
struct S_with_array {
int m1, m2;
int data[10];
};
void pointer_member_deref() {
S_with_array s;
taint_a_ptr(s.data);
sink(*s.data); // $ir,ast
}
void array_member_deref() {
S_with_array s;
taint_a_ptr(s.data);
sink(s.data[0]); // $ir,ast
}
struct S2 {
S s;
int m3;
};
void deep_member_field_dot() {
S2 s2;
taint_a_ptr(&s2.s.m1);
sink(s2.s.m1); // $ir,ast
}
void deep_member_field_dot_different_fields() {
S2 s2;
taint_a_ptr(&s2.s.m1);
sink(s2.s.m2);
}
void deep_member_field_dot_2() {
S2 s2;
taint_a_ptr(&s2.s.m1);
S2 s2_2 = s2;
sink(s2_2.s.m1); // $ir,ast
}
void deep_member_field_dot_different_fields_2() {
S2 s2;
taint_a_ptr(&s2.s.m1);
S2 s2_2 = s2;
sink(s2_2.s.m2);
}
void deep_member_field_arrow(S2 *ps2) {
taint_a_ptr(&ps2->s.m1);
sink(ps2->s.m1); // $ir,ast
}
void deep_member_field_arrow_different_fields(S2 *ps2) {
taint_a_ptr(&ps2->s.m1);
sink(ps2->s.m2);
}

View File

@@ -0,0 +1,51 @@
void sink(void *o);
void *user_input(void);
void local_array() {
void *arr[10] = { 0 };
arr[0] = user_input();
sink(arr[0]); // $ast,ir
sink(arr[1]); // $f+:ast
sink(*arr); // $ast,ir
sink(*&arr[0]); // $ast,ir
}
void local_array_convoluted_assign() {
void *arr[10] = { 0 };
*&arr[0] = user_input();
sink(arr[0]); // $ast,ir
sink(arr[1]); // $f+:ast
}
struct inner {
void *data;
int unrelated;
};
struct middle {
inner arr[10];
inner *ptr;
};
struct outer {
middle nested;
middle *indirect;
};
void nested_array_1(outer o) {
o.nested.arr[1].data = user_input();
sink(o.nested.arr[1].data); // $ast,ir
sink(o.nested.arr[0].data); // $f+:ast
}
void nested_array_2(outer o) {
o.indirect->arr[1].data = user_input();
sink(o.indirect->arr[1].data); // $ast $f-:ir
sink(o.indirect->arr[0].data); // $f+:ast
}
void nested_array_3(outer o) {
o.indirect->ptr[1].data = user_input();
sink(o.indirect->ptr[1].data); // $f-:ast,ir
sink(o.indirect->ptr[0].data);
}

View File

@@ -109,11 +109,11 @@ void test_outer_with_ptr(Outer *pouter) {
sink(outer.inner_nested.a); // $ast,ir
sink(outer.inner_ptr->a); // $ast $f-:ir
sink(outer.a); // $f-:ast $f-:ir
sink(outer.a); // $ast,ir
sink(pouter->inner_nested.a); // $ast,ir
sink(pouter->inner_ptr->a); // $ast $f-:ir
sink(pouter->a); // $f-:ast $f-:ir
sink(pouter->a); // $ast,ir
}
void test_outer_with_ref(Outer *pouter) {
@@ -129,9 +129,9 @@ void test_outer_with_ref(Outer *pouter) {
sink(outer.inner_nested.a); // $ast,ir
sink(outer.inner_ptr->a); // $ast $f-:ir
sink(outer.a); // $ast $f-:ir
sink(outer.a); // $ast,ir
sink(pouter->inner_nested.a); // $ast,ir
sink(pouter->inner_ptr->a); // $ast $f-:ir
sink(pouter->a); // $ast $f-:ir
sink(pouter->a); // $ast,ir
}

View File

@@ -30,6 +30,12 @@ argHasPostUpdate
| D.cpp:43:24:43:40 | new | ArgumentNode is missing PostUpdateNode. |
| D.cpp:50:24:50:40 | new | ArgumentNode is missing PostUpdateNode. |
| D.cpp:57:25:57:41 | new | ArgumentNode is missing PostUpdateNode. |
| arrays.cpp:7:8:7:13 | access to array | ArgumentNode is missing PostUpdateNode. |
| arrays.cpp:8:8:8:13 | access to array | ArgumentNode is missing PostUpdateNode. |
| arrays.cpp:9:8:9:11 | * ... | ArgumentNode is missing PostUpdateNode. |
| arrays.cpp:10:8:10:15 | * ... | ArgumentNode is missing PostUpdateNode. |
| arrays.cpp:16:8:16:13 | access to array | ArgumentNode is missing PostUpdateNode. |
| arrays.cpp:17:8:17:13 | access to array | ArgumentNode is missing PostUpdateNode. |
| by_reference.cpp:51:8:51:8 | s | ArgumentNode is missing PostUpdateNode. |
| by_reference.cpp:57:8:57:8 | s | ArgumentNode is missing PostUpdateNode. |
| by_reference.cpp:63:8:63:8 | s | ArgumentNode is missing PostUpdateNode. |

View File

@@ -1,13 +1,10 @@
uniqueEnclosingCallable
uniqueType
uniqueNodeLocation
| D.cpp:1:17:1:17 | o | Node should have one location but has 3. |
| by_reference.cpp:1:17:1:17 | o | Node should have one location but has 3. |
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
| qualifiers.cpp:1:17:1:17 | o | Node should have one location but has 3. |
missingLocation
| Nodes without location: 4 |
uniqueNodeToString
@@ -20,6 +17,7 @@ localCallNodes
postIsNotPre
postHasUniquePre
| simple.cpp:65:5:65:22 | Store | PostUpdateNode should have one pre-update node but has 0. |
| simple.cpp:92:5:92:22 | Store | PostUpdateNode should have one pre-update node but has 0. |
uniquePostUpdate
postIsInSameCallable
reverseRead

View File

@@ -21,12 +21,19 @@
| aliasing.cpp:79:11:79:20 | call to user_input | aliasing.cpp:80:12:80:13 | m1 | IR only |
| aliasing.cpp:86:10:86:19 | call to user_input | aliasing.cpp:87:12:87:13 | m1 | IR only |
| aliasing.cpp:98:10:98:19 | call to user_input | aliasing.cpp:102:8:102:10 | * ... | IR only |
| aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:122:8:122:12 | access to array | IR only |
| aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:127:8:127:16 | * ... | IR only |
| aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:132:8:132:14 | * ... | IR only |
| aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:137:8:137:11 | * ... | IR only |
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:8:8:8:13 | access to array | AST only |
| arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:17:8:17:13 | access to array | AST only |
| arrays.cpp:36:26:36:35 | call to user_input | arrays.cpp:38:24:38:27 | data | AST only |
| arrays.cpp:42:29:42:38 | call to user_input | arrays.cpp:43:27:43:30 | data | AST only |
| arrays.cpp:42:29:42:38 | call to user_input | arrays.cpp:44:27:44:30 | data | AST only |
| by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:111:25:111:25 | a | AST only |
| by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:115:27:115:27 | a | AST only |
| by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:131:25:131:25 | a | AST only |
| by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:135:27:135:27 | a | AST only |
| by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:132:14:132:14 | a | AST only |
| by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:136:16:136:16 | a | AST only |
| complex.cpp:62:19:62:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | AST only |
| complex.cpp:63:19:63:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | AST only |
| complex.cpp:64:19:64:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | AST only |
@@ -37,5 +44,6 @@
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:38:23:38:23 | a | AST only |
| qualifiers.cpp:42:29:42:38 | call to user_input | qualifiers.cpp:43:23:43:23 | a | AST only |
| qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:48:23:48:23 | a | AST only |
| realistic.cpp:53:55:53:64 | call to user_input | realistic.cpp:61:47:61:55 | bufferLen | AST only |
| struct_init.c:20:20:20:29 | call to user_input | struct_init.c:33:25:33:25 | a | AST only |
| struct_init.c:40:20:40:29 | call to user_input | struct_init.c:15:12:15:12 | a | AST only |

View File

@@ -64,6 +64,44 @@ edges
| aliasing.cpp:98:3:98:21 | Store | aliasing.cpp:98:3:98:21 | Chi [m1] |
| aliasing.cpp:98:10:98:19 | call to user_input | aliasing.cpp:98:3:98:21 | Store |
| aliasing.cpp:100:14:100:14 | Store [m1] | aliasing.cpp:102:8:102:10 | * ... |
| aliasing.cpp:106:3:106:20 | Chi [array content] | aliasing.cpp:121:15:121:16 | taint_a_ptr output argument [array content] |
| aliasing.cpp:106:3:106:20 | Chi [array content] | aliasing.cpp:126:15:126:20 | taint_a_ptr output argument [array content] |
| aliasing.cpp:106:3:106:20 | Chi [array content] | aliasing.cpp:131:15:131:16 | taint_a_ptr output argument [array content] |
| aliasing.cpp:106:3:106:20 | Chi [array content] | aliasing.cpp:136:15:136:17 | taint_a_ptr output argument [array content] |
| aliasing.cpp:106:3:106:20 | Chi [array content] | aliasing.cpp:158:15:158:20 | taint_a_ptr output argument [array content] |
| aliasing.cpp:106:3:106:20 | Chi [array content] | aliasing.cpp:164:15:164:20 | taint_a_ptr output argument [array content] |
| aliasing.cpp:106:3:106:20 | Chi [array content] | aliasing.cpp:175:15:175:22 | taint_a_ptr output argument [array content] |
| aliasing.cpp:106:3:106:20 | Chi [array content] | aliasing.cpp:187:15:187:22 | taint_a_ptr output argument [array content] |
| aliasing.cpp:106:3:106:20 | Chi [array content] | aliasing.cpp:200:15:200:24 | taint_a_ptr output argument [array content] |
| aliasing.cpp:106:3:106:20 | Store | aliasing.cpp:106:3:106:20 | Chi [array content] |
| aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:106:3:106:20 | Store |
| aliasing.cpp:121:15:121:16 | Chi [array content] | aliasing.cpp:122:8:122:12 | access to array |
| aliasing.cpp:121:15:121:16 | taint_a_ptr output argument [array content] | aliasing.cpp:121:15:121:16 | Chi [array content] |
| aliasing.cpp:126:15:126:20 | Chi [array content] | aliasing.cpp:127:8:127:16 | * ... |
| aliasing.cpp:126:15:126:20 | taint_a_ptr output argument [array content] | aliasing.cpp:126:15:126:20 | Chi [array content] |
| aliasing.cpp:131:15:131:16 | Chi [array content] | aliasing.cpp:132:8:132:14 | * ... |
| aliasing.cpp:131:15:131:16 | taint_a_ptr output argument [array content] | aliasing.cpp:131:15:131:16 | Chi [array content] |
| aliasing.cpp:136:15:136:17 | Chi [array content] | aliasing.cpp:137:8:137:11 | * ... |
| aliasing.cpp:136:15:136:17 | taint_a_ptr output argument [array content] | aliasing.cpp:136:15:136:17 | Chi [array content] |
| aliasing.cpp:158:15:158:20 | Chi [array content] | aliasing.cpp:159:8:159:14 | * ... |
| aliasing.cpp:158:15:158:20 | taint_a_ptr output argument [array content] | aliasing.cpp:158:15:158:20 | Chi [array content] |
| aliasing.cpp:164:15:164:20 | Chi [array content] | aliasing.cpp:165:8:165:16 | access to array |
| aliasing.cpp:164:15:164:20 | taint_a_ptr output argument [array content] | aliasing.cpp:164:15:164:20 | Chi [array content] |
| aliasing.cpp:175:15:175:22 | Chi | aliasing.cpp:175:15:175:22 | Chi [m1] |
| aliasing.cpp:175:15:175:22 | Chi [m1] | aliasing.cpp:176:13:176:14 | m1 |
| aliasing.cpp:175:15:175:22 | taint_a_ptr output argument [array content] | aliasing.cpp:175:15:175:22 | Chi |
| aliasing.cpp:187:15:187:22 | Chi | aliasing.cpp:187:15:187:22 | Chi [m1] |
| aliasing.cpp:187:15:187:22 | Chi [m1] | aliasing.cpp:188:13:188:14 | Store [m1] |
| aliasing.cpp:187:15:187:22 | taint_a_ptr output argument [array content] | aliasing.cpp:187:15:187:22 | Chi |
| aliasing.cpp:188:13:188:14 | Store [m1] | aliasing.cpp:189:15:189:16 | m1 |
| aliasing.cpp:200:15:200:24 | Chi | aliasing.cpp:200:15:200:24 | Chi [m1] |
| aliasing.cpp:200:15:200:24 | Chi [m1] | aliasing.cpp:201:15:201:16 | m1 |
| aliasing.cpp:200:15:200:24 | taint_a_ptr output argument [array content] | aliasing.cpp:200:15:200:24 | Chi |
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:7:8:7:13 | access to array |
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:9:8:9:11 | * ... |
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:10:8:10:15 | * ... |
| arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:16:8:16:13 | access to array |
| arrays.cpp:36:26:36:35 | call to user_input | arrays.cpp:37:24:37:27 | data |
| by_reference.cpp:50:3:50:3 | setDirectly output argument [a] | by_reference.cpp:51:8:51:8 | Argument -1 indirection [a] |
| by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:50:3:50:3 | setDirectly output argument [a] |
| by_reference.cpp:51:8:51:8 | Argument -1 indirection [a] | by_reference.cpp:51:10:51:20 | call to getDirectly |
@@ -84,14 +122,34 @@ edges
| by_reference.cpp:88:3:88:24 | Chi [a] | by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] |
| by_reference.cpp:88:3:88:24 | Store | by_reference.cpp:88:3:88:24 | Chi [a] |
| by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:88:3:88:24 | Store |
| by_reference.cpp:92:3:92:20 | Chi [array content] | by_reference.cpp:104:15:104:22 | taint_a_ptr output argument [array content] |
| by_reference.cpp:92:3:92:20 | Chi [array content] | by_reference.cpp:108:15:108:24 | taint_a_ptr output argument [array content] |
| by_reference.cpp:92:3:92:20 | Store | by_reference.cpp:92:3:92:20 | Chi [array content] |
| by_reference.cpp:92:9:92:18 | call to user_input | by_reference.cpp:92:3:92:20 | Store |
| by_reference.cpp:96:3:96:19 | Chi [array content] | by_reference.cpp:124:15:124:21 | taint_a_ref output argument [array content] |
| by_reference.cpp:96:3:96:19 | Chi [array content] | by_reference.cpp:128:15:128:23 | taint_a_ref output argument [array content] |
| by_reference.cpp:96:3:96:19 | Store | by_reference.cpp:96:3:96:19 | Chi [array content] |
| by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:96:3:96:19 | Store |
| by_reference.cpp:102:21:102:39 | Chi [a] | by_reference.cpp:110:27:110:27 | a |
| by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] | by_reference.cpp:102:21:102:39 | Chi [a] |
| by_reference.cpp:104:15:104:22 | Chi | by_reference.cpp:104:15:104:22 | Chi [a] |
| by_reference.cpp:104:15:104:22 | Chi [a] | by_reference.cpp:112:14:112:14 | a |
| by_reference.cpp:104:15:104:22 | taint_a_ptr output argument [array content] | by_reference.cpp:104:15:104:22 | Chi |
| by_reference.cpp:106:21:106:41 | Chi [a] | by_reference.cpp:114:29:114:29 | a |
| by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] | by_reference.cpp:106:21:106:41 | Chi [a] |
| by_reference.cpp:108:15:108:24 | Chi | by_reference.cpp:108:15:108:24 | Chi [a] |
| by_reference.cpp:108:15:108:24 | Chi [a] | by_reference.cpp:116:16:116:16 | a |
| by_reference.cpp:108:15:108:24 | taint_a_ptr output argument [array content] | by_reference.cpp:108:15:108:24 | Chi |
| by_reference.cpp:122:21:122:38 | Chi [a] | by_reference.cpp:130:27:130:27 | a |
| by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | by_reference.cpp:122:21:122:38 | Chi [a] |
| by_reference.cpp:124:15:124:21 | Chi | by_reference.cpp:124:15:124:21 | Chi [a] |
| by_reference.cpp:124:15:124:21 | Chi [a] | by_reference.cpp:132:14:132:14 | a |
| by_reference.cpp:124:15:124:21 | taint_a_ref output argument [array content] | by_reference.cpp:124:15:124:21 | Chi |
| by_reference.cpp:126:21:126:40 | Chi [a] | by_reference.cpp:134:29:134:29 | a |
| by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] | by_reference.cpp:126:21:126:40 | Chi [a] |
| by_reference.cpp:128:15:128:23 | Chi | by_reference.cpp:128:15:128:23 | Chi [a] |
| by_reference.cpp:128:15:128:23 | Chi [a] | by_reference.cpp:136:16:136:16 | a |
| by_reference.cpp:128:15:128:23 | taint_a_ref output argument [array content] | by_reference.cpp:128:15:128:23 | Chi |
| complex.cpp:40:17:40:17 | *b [a_] | complex.cpp:51:16:51:16 | Argument -1 indirection [a_] |
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:51:16:51:16 | Argument -1 indirection [b_] |
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:52:16:52:16 | Argument -1 indirection [b_] |
@@ -162,6 +220,9 @@ edges
| simple.cpp:83:9:83:28 | Store | simple.cpp:83:9:83:28 | Chi [f1] |
| simple.cpp:83:17:83:26 | call to user_input | simple.cpp:83:9:83:28 | Store |
| simple.cpp:84:14:84:20 | Argument -1 indirection [f1] | simple.cpp:84:14:84:20 | call to getf2f1 |
| simple.cpp:92:5:92:22 | Store [i] | simple.cpp:93:20:93:20 | Store [i] |
| simple.cpp:92:11:92:20 | call to user_input | simple.cpp:92:5:92:22 | Store [i] |
| simple.cpp:93:20:93:20 | Store [i] | simple.cpp:94:13:94:13 | i |
| struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:15:12:15:12 | a |
| struct_init.c:20:20:20:29 | Chi [a] | struct_init.c:24:10:24:12 | Argument 0 indirection [a] |
| struct_init.c:20:20:20:29 | Store | struct_init.c:20:20:20:29 | Chi [a] |
@@ -256,6 +317,48 @@ nodes
| aliasing.cpp:98:10:98:19 | call to user_input | semmle.label | call to user_input |
| aliasing.cpp:100:14:100:14 | Store [m1] | semmle.label | Store [m1] |
| aliasing.cpp:102:8:102:10 | * ... | semmle.label | * ... |
| aliasing.cpp:106:3:106:20 | Chi [array content] | semmle.label | Chi [array content] |
| aliasing.cpp:106:3:106:20 | Store | semmle.label | Store |
| aliasing.cpp:106:9:106:18 | call to user_input | semmle.label | call to user_input |
| aliasing.cpp:121:15:121:16 | Chi [array content] | semmle.label | Chi [array content] |
| aliasing.cpp:121:15:121:16 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
| aliasing.cpp:122:8:122:12 | access to array | semmle.label | access to array |
| aliasing.cpp:126:15:126:20 | Chi [array content] | semmle.label | Chi [array content] |
| aliasing.cpp:126:15:126:20 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
| aliasing.cpp:127:8:127:16 | * ... | semmle.label | * ... |
| aliasing.cpp:131:15:131:16 | Chi [array content] | semmle.label | Chi [array content] |
| aliasing.cpp:131:15:131:16 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
| aliasing.cpp:132:8:132:14 | * ... | semmle.label | * ... |
| aliasing.cpp:136:15:136:17 | Chi [array content] | semmle.label | Chi [array content] |
| aliasing.cpp:136:15:136:17 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
| aliasing.cpp:137:8:137:11 | * ... | semmle.label | * ... |
| aliasing.cpp:158:15:158:20 | Chi [array content] | semmle.label | Chi [array content] |
| aliasing.cpp:158:15:158:20 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
| aliasing.cpp:159:8:159:14 | * ... | semmle.label | * ... |
| aliasing.cpp:164:15:164:20 | Chi [array content] | semmle.label | Chi [array content] |
| aliasing.cpp:164:15:164:20 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
| aliasing.cpp:165:8:165:16 | access to array | semmle.label | access to array |
| aliasing.cpp:175:15:175:22 | Chi | semmle.label | Chi |
| aliasing.cpp:175:15:175:22 | Chi [m1] | semmle.label | Chi [m1] |
| aliasing.cpp:175:15:175:22 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
| aliasing.cpp:176:13:176:14 | m1 | semmle.label | m1 |
| aliasing.cpp:187:15:187:22 | Chi | semmle.label | Chi |
| aliasing.cpp:187:15:187:22 | Chi [m1] | semmle.label | Chi [m1] |
| aliasing.cpp:187:15:187:22 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
| aliasing.cpp:188:13:188:14 | Store [m1] | semmle.label | Store [m1] |
| aliasing.cpp:189:15:189:16 | m1 | semmle.label | m1 |
| aliasing.cpp:200:15:200:24 | Chi | semmle.label | Chi |
| aliasing.cpp:200:15:200:24 | Chi [m1] | semmle.label | Chi [m1] |
| aliasing.cpp:200:15:200:24 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
| aliasing.cpp:201:15:201:16 | m1 | semmle.label | m1 |
| arrays.cpp:6:12:6:21 | call to user_input | semmle.label | call to user_input |
| arrays.cpp:7:8:7:13 | access to array | semmle.label | access to array |
| arrays.cpp:9:8:9:11 | * ... | semmle.label | * ... |
| arrays.cpp:10:8:10:15 | * ... | semmle.label | * ... |
| arrays.cpp:15:14:15:23 | call to user_input | semmle.label | call to user_input |
| arrays.cpp:16:8:16:13 | access to array | semmle.label | access to array |
| arrays.cpp:36:26:36:35 | call to user_input | semmle.label | call to user_input |
| arrays.cpp:37:24:37:27 | data | semmle.label | data |
| by_reference.cpp:50:3:50:3 | setDirectly output argument [a] | semmle.label | setDirectly output argument [a] |
| by_reference.cpp:50:17:50:26 | call to user_input | semmle.label | call to user_input |
| by_reference.cpp:51:8:51:8 | Argument -1 indirection [a] | semmle.label | Argument -1 indirection [a] |
@@ -278,18 +381,40 @@ nodes
| by_reference.cpp:88:3:88:24 | Chi [a] | semmle.label | Chi [a] |
| by_reference.cpp:88:3:88:24 | Store | semmle.label | Store |
| by_reference.cpp:88:13:88:22 | call to user_input | semmle.label | call to user_input |
| by_reference.cpp:92:3:92:20 | Chi [array content] | semmle.label | Chi [array content] |
| by_reference.cpp:92:3:92:20 | Store | semmle.label | Store |
| by_reference.cpp:92:9:92:18 | call to user_input | semmle.label | call to user_input |
| by_reference.cpp:96:3:96:19 | Chi [array content] | semmle.label | Chi [array content] |
| by_reference.cpp:96:3:96:19 | Store | semmle.label | Store |
| by_reference.cpp:96:8:96:17 | call to user_input | semmle.label | call to user_input |
| by_reference.cpp:102:21:102:39 | Chi [a] | semmle.label | Chi [a] |
| by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] | semmle.label | taint_inner_a_ptr output argument [a] |
| by_reference.cpp:104:15:104:22 | Chi | semmle.label | Chi |
| by_reference.cpp:104:15:104:22 | Chi [a] | semmle.label | Chi [a] |
| by_reference.cpp:104:15:104:22 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
| by_reference.cpp:106:21:106:41 | Chi [a] | semmle.label | Chi [a] |
| by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] | semmle.label | taint_inner_a_ptr output argument [a] |
| by_reference.cpp:108:15:108:24 | Chi | semmle.label | Chi |
| by_reference.cpp:108:15:108:24 | Chi [a] | semmle.label | Chi [a] |
| by_reference.cpp:108:15:108:24 | taint_a_ptr output argument [array content] | semmle.label | taint_a_ptr output argument [array content] |
| by_reference.cpp:110:27:110:27 | a | semmle.label | a |
| by_reference.cpp:112:14:112:14 | a | semmle.label | a |
| by_reference.cpp:114:29:114:29 | a | semmle.label | a |
| by_reference.cpp:116:16:116:16 | a | semmle.label | a |
| by_reference.cpp:122:21:122:38 | Chi [a] | semmle.label | Chi [a] |
| by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | semmle.label | taint_inner_a_ref output argument [a] |
| by_reference.cpp:124:15:124:21 | Chi | semmle.label | Chi |
| by_reference.cpp:124:15:124:21 | Chi [a] | semmle.label | Chi [a] |
| by_reference.cpp:124:15:124:21 | taint_a_ref output argument [array content] | semmle.label | taint_a_ref output argument [array content] |
| by_reference.cpp:126:21:126:40 | Chi [a] | semmle.label | Chi [a] |
| by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] | semmle.label | taint_inner_a_ref output argument [a] |
| by_reference.cpp:128:15:128:23 | Chi | semmle.label | Chi |
| by_reference.cpp:128:15:128:23 | Chi [a] | semmle.label | Chi [a] |
| by_reference.cpp:128:15:128:23 | taint_a_ref output argument [array content] | semmle.label | taint_a_ref output argument [array content] |
| by_reference.cpp:130:27:130:27 | a | semmle.label | a |
| by_reference.cpp:132:14:132:14 | a | semmle.label | a |
| by_reference.cpp:134:29:134:29 | a | semmle.label | a |
| by_reference.cpp:136:16:136:16 | a | semmle.label | a |
| complex.cpp:40:17:40:17 | *b [a_] | semmle.label | *b [a_] |
| complex.cpp:40:17:40:17 | *b [b_] | semmle.label | *b [b_] |
| complex.cpp:51:16:51:16 | Argument -1 indirection [a_] | semmle.label | Argument -1 indirection [a_] |
@@ -363,6 +488,10 @@ nodes
| simple.cpp:83:17:83:26 | call to user_input | semmle.label | call to user_input |
| simple.cpp:84:14:84:20 | Argument -1 indirection [f1] | semmle.label | Argument -1 indirection [f1] |
| simple.cpp:84:14:84:20 | call to getf2f1 | semmle.label | call to getf2f1 |
| simple.cpp:92:5:92:22 | Store [i] | semmle.label | Store [i] |
| simple.cpp:92:11:92:20 | call to user_input | semmle.label | call to user_input |
| simple.cpp:93:20:93:20 | Store [i] | semmle.label | Store [i] |
| simple.cpp:94:13:94:13 | i | semmle.label | i |
| struct_init.c:14:24:14:25 | *ab [a] | semmle.label | *ab [a] |
| struct_init.c:15:12:15:12 | a | semmle.label | a |
| struct_init.c:20:20:20:29 | Chi [a] | semmle.label | Chi [a] |
@@ -395,14 +524,32 @@ nodes
| aliasing.cpp:87:12:87:13 | m1 | aliasing.cpp:86:10:86:19 | call to user_input | aliasing.cpp:87:12:87:13 | m1 | m1 flows from $@ | aliasing.cpp:86:10:86:19 | call to user_input | call to user_input |
| aliasing.cpp:93:12:93:13 | m1 | aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:93:12:93:13 | m1 | m1 flows from $@ | aliasing.cpp:92:12:92:21 | call to user_input | call to user_input |
| aliasing.cpp:102:8:102:10 | * ... | aliasing.cpp:98:10:98:19 | call to user_input | aliasing.cpp:102:8:102:10 | * ... | * ... flows from $@ | aliasing.cpp:98:10:98:19 | call to user_input | call to user_input |
| aliasing.cpp:122:8:122:12 | access to array | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:122:8:122:12 | access to array | access to array flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
| aliasing.cpp:127:8:127:16 | * ... | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:127:8:127:16 | * ... | * ... flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
| aliasing.cpp:132:8:132:14 | * ... | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:132:8:132:14 | * ... | * ... flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
| aliasing.cpp:137:8:137:11 | * ... | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:137:8:137:11 | * ... | * ... flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
| aliasing.cpp:159:8:159:14 | * ... | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:159:8:159:14 | * ... | * ... flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
| aliasing.cpp:165:8:165:16 | access to array | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:165:8:165:16 | access to array | access to array flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
| aliasing.cpp:176:13:176:14 | m1 | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:176:13:176:14 | m1 | m1 flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
| aliasing.cpp:189:15:189:16 | m1 | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:189:15:189:16 | m1 | m1 flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
| aliasing.cpp:201:15:201:16 | m1 | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:201:15:201:16 | m1 | m1 flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
| arrays.cpp:7:8:7:13 | access to array | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:7:8:7:13 | access to array | access to array flows from $@ | arrays.cpp:6:12:6:21 | call to user_input | call to user_input |
| arrays.cpp:9:8:9:11 | * ... | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:9:8:9:11 | * ... | * ... flows from $@ | arrays.cpp:6:12:6:21 | call to user_input | call to user_input |
| arrays.cpp:10:8:10:15 | * ... | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:10:8:10:15 | * ... | * ... flows from $@ | arrays.cpp:6:12:6:21 | call to user_input | call to user_input |
| arrays.cpp:16:8:16:13 | access to array | arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:16:8:16:13 | access to array | access to array flows from $@ | arrays.cpp:15:14:15:23 | call to user_input | call to user_input |
| arrays.cpp:37:24:37:27 | data | arrays.cpp:36:26:36:35 | call to user_input | arrays.cpp:37:24:37:27 | data | data flows from $@ | arrays.cpp:36:26:36:35 | call to user_input | call to user_input |
| by_reference.cpp:51:10:51:20 | call to getDirectly | by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:51:10:51:20 | call to getDirectly | call to getDirectly flows from $@ | by_reference.cpp:50:17:50:26 | call to user_input | call to user_input |
| by_reference.cpp:57:10:57:22 | call to getIndirectly | by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:57:10:57:22 | call to getIndirectly | call to getIndirectly flows from $@ | by_reference.cpp:56:19:56:28 | call to user_input | call to user_input |
| by_reference.cpp:63:10:63:28 | call to getThroughNonMember | by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:63:10:63:28 | call to getThroughNonMember | call to getThroughNonMember flows from $@ | by_reference.cpp:62:25:62:34 | call to user_input | call to user_input |
| by_reference.cpp:69:8:69:20 | call to nonMemberGetA | by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:69:8:69:20 | call to nonMemberGetA | call to nonMemberGetA flows from $@ | by_reference.cpp:68:21:68:30 | call to user_input | call to user_input |
| by_reference.cpp:110:27:110:27 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:110:27:110:27 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
| by_reference.cpp:112:14:112:14 | a | by_reference.cpp:92:9:92:18 | call to user_input | by_reference.cpp:112:14:112:14 | a | a flows from $@ | by_reference.cpp:92:9:92:18 | call to user_input | call to user_input |
| by_reference.cpp:114:29:114:29 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:114:29:114:29 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
| by_reference.cpp:116:16:116:16 | a | by_reference.cpp:92:9:92:18 | call to user_input | by_reference.cpp:116:16:116:16 | a | a flows from $@ | by_reference.cpp:92:9:92:18 | call to user_input | call to user_input |
| by_reference.cpp:130:27:130:27 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:130:27:130:27 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
| by_reference.cpp:132:14:132:14 | a | by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:132:14:132:14 | a | a flows from $@ | by_reference.cpp:96:8:96:17 | call to user_input | call to user_input |
| by_reference.cpp:134:29:134:29 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:134:29:134:29 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
| by_reference.cpp:136:16:136:16 | a | by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:136:16:136:16 | a | a flows from $@ | by_reference.cpp:96:8:96:17 | call to user_input | call to user_input |
| complex.cpp:51:18:51:18 | call to a | complex.cpp:62:19:62:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | call to a flows from $@ | complex.cpp:62:19:62:28 | call to user_input | call to user_input |
| complex.cpp:51:18:51:18 | call to a | complex.cpp:64:19:64:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | call to a flows from $@ | complex.cpp:64:19:64:28 | call to user_input | call to user_input |
| complex.cpp:52:18:52:18 | call to b | complex.cpp:63:19:63:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | call to b flows from $@ | complex.cpp:63:19:63:28 | call to user_input | call to user_input |
@@ -417,6 +564,7 @@ nodes
| simple.cpp:29:12:29:12 | call to b | simple.cpp:42:12:42:21 | call to user_input | simple.cpp:29:12:29:12 | call to b | call to b flows from $@ | simple.cpp:42:12:42:21 | call to user_input | call to user_input |
| simple.cpp:67:13:67:13 | i | simple.cpp:65:11:65:20 | call to user_input | simple.cpp:67:13:67:13 | i | i flows from $@ | simple.cpp:65:11:65:20 | call to user_input | call to user_input |
| simple.cpp:84:14:84:20 | call to getf2f1 | simple.cpp:83:17:83:26 | call to user_input | simple.cpp:84:14:84:20 | call to getf2f1 | call to getf2f1 flows from $@ | simple.cpp:83:17:83:26 | call to user_input | call to user_input |
| simple.cpp:94:13:94:13 | i | simple.cpp:92:11:92:20 | call to user_input | simple.cpp:94:13:94:13 | i | i flows from $@ | simple.cpp:92:11:92:20 | call to user_input | call to user_input |
| struct_init.c:15:12:15:12 | a | struct_init.c:20:20:20:29 | call to user_input | struct_init.c:15:12:15:12 | a | a flows from $@ | struct_init.c:20:20:20:29 | call to user_input | call to user_input |
| struct_init.c:15:12:15:12 | a | struct_init.c:27:7:27:16 | call to user_input | struct_init.c:15:12:15:12 | a | a flows from $@ | struct_init.c:27:7:27:16 | call to user_input | call to user_input |
| struct_init.c:22:11:22:11 | a | struct_init.c:20:20:20:29 | call to user_input | struct_init.c:22:11:22:11 | a | a flows from $@ | struct_init.c:20:20:20:29 | call to user_input | call to user_input |

View File

@@ -158,6 +158,69 @@
| aliasing.cpp:92:3:92:3 | w | AST only |
| aliasing.cpp:92:7:92:8 | m1 | AST only |
| aliasing.cpp:98:5:98:6 | m1 | AST only |
| aliasing.cpp:106:3:106:5 | * ... | AST only |
| aliasing.cpp:111:15:111:19 | & ... | AST only |
| aliasing.cpp:121:15:121:16 | xs | AST only |
| aliasing.cpp:126:15:126:20 | ... - ... | AST only |
| aliasing.cpp:131:15:131:16 | xs | AST only |
| aliasing.cpp:136:15:136:17 | + ... | AST only |
| aliasing.cpp:141:15:141:15 | s | AST only |
| aliasing.cpp:141:17:141:20 | data | AST only |
| aliasing.cpp:147:15:147:22 | & ... | AST only |
| aliasing.cpp:158:15:158:15 | s | AST only |
| aliasing.cpp:158:17:158:20 | data | AST only |
| aliasing.cpp:164:15:164:15 | s | AST only |
| aliasing.cpp:164:17:164:20 | data | AST only |
| aliasing.cpp:175:15:175:22 | & ... | AST only |
| aliasing.cpp:175:16:175:17 | s2 | AST only |
| aliasing.cpp:181:15:181:22 | & ... | AST only |
| aliasing.cpp:181:16:181:17 | s2 | AST only |
| aliasing.cpp:187:15:187:22 | & ... | AST only |
| aliasing.cpp:187:16:187:17 | s2 | AST only |
| aliasing.cpp:194:15:194:22 | & ... | AST only |
| aliasing.cpp:194:16:194:17 | s2 | AST only |
| aliasing.cpp:200:15:200:24 | & ... | AST only |
| aliasing.cpp:200:16:200:18 | ps2 | AST only |
| aliasing.cpp:205:15:205:24 | & ... | AST only |
| aliasing.cpp:205:16:205:18 | ps2 | AST only |
| arrays.cpp:6:3:6:8 | access to array | AST only |
| arrays.cpp:6:3:6:23 | arr | IR only |
| arrays.cpp:15:3:15:10 | * ... | AST only |
| arrays.cpp:36:3:36:3 | o | AST only |
| arrays.cpp:36:5:36:10 | nested | AST only |
| arrays.cpp:36:19:36:22 | data | AST only |
| arrays.cpp:37:8:37:8 | o | AST only |
| arrays.cpp:37:8:37:22 | access to array | AST only |
| arrays.cpp:37:10:37:15 | nested | AST only |
| arrays.cpp:37:24:37:27 | data | AST only |
| arrays.cpp:38:8:38:8 | o | AST only |
| arrays.cpp:38:8:38:22 | access to array | AST only |
| arrays.cpp:38:10:38:15 | nested | AST only |
| arrays.cpp:38:24:38:27 | data | AST only |
| arrays.cpp:42:3:42:3 | o | AST only |
| arrays.cpp:42:3:42:20 | access to array | AST only |
| arrays.cpp:42:5:42:12 | indirect | AST only |
| arrays.cpp:42:22:42:25 | data | AST only |
| arrays.cpp:43:8:43:8 | o | AST only |
| arrays.cpp:43:8:43:25 | access to array | AST only |
| arrays.cpp:43:10:43:17 | indirect | AST only |
| arrays.cpp:43:27:43:30 | data | AST only |
| arrays.cpp:44:8:44:8 | o | AST only |
| arrays.cpp:44:8:44:25 | access to array | AST only |
| arrays.cpp:44:10:44:17 | indirect | AST only |
| arrays.cpp:44:27:44:30 | data | AST only |
| arrays.cpp:48:3:48:3 | o | AST only |
| arrays.cpp:48:3:48:20 | access to array | AST only |
| arrays.cpp:48:5:48:12 | indirect | AST only |
| arrays.cpp:48:22:48:25 | data | AST only |
| arrays.cpp:49:8:49:8 | o | AST only |
| arrays.cpp:49:8:49:25 | access to array | AST only |
| arrays.cpp:49:10:49:17 | indirect | AST only |
| arrays.cpp:49:27:49:30 | data | AST only |
| arrays.cpp:50:8:50:8 | o | AST only |
| arrays.cpp:50:8:50:25 | access to array | AST only |
| arrays.cpp:50:10:50:17 | indirect | AST only |
| arrays.cpp:50:27:50:30 | data | AST only |
| by_reference.cpp:12:8:12:8 | a | AST only |
| by_reference.cpp:16:11:16:11 | a | AST only |
| by_reference.cpp:20:5:20:8 | this | AST only |
@@ -178,18 +241,16 @@
| by_reference.cpp:69:8:69:20 | call to nonMemberGetA | AST only |
| by_reference.cpp:84:10:84:10 | a | AST only |
| by_reference.cpp:88:9:88:9 | a | AST only |
| by_reference.cpp:92:3:92:5 | * ... | AST only |
| by_reference.cpp:96:3:96:4 | pa | AST only |
| by_reference.cpp:102:21:102:39 | & ... | AST only |
| by_reference.cpp:102:22:102:26 | outer | AST only |
| by_reference.cpp:103:21:103:25 | outer | AST only |
| by_reference.cpp:103:27:103:35 | inner_ptr | AST only |
| by_reference.cpp:104:15:104:22 | & ... | AST only |
| by_reference.cpp:104:16:104:20 | outer | AST only |
| by_reference.cpp:106:21:106:41 | & ... | AST only |
| by_reference.cpp:106:22:106:27 | pouter | AST only |
| by_reference.cpp:107:21:107:26 | pouter | AST only |
| by_reference.cpp:107:29:107:37 | inner_ptr | AST only |
| by_reference.cpp:108:15:108:24 | & ... | AST only |
| by_reference.cpp:108:16:108:21 | pouter | AST only |
| by_reference.cpp:110:8:110:12 | outer | AST only |
| by_reference.cpp:110:14:110:25 | inner_nested | AST only |
| by_reference.cpp:110:27:110:27 | a | AST only |
@@ -206,17 +267,13 @@
| by_reference.cpp:115:27:115:27 | a | AST only |
| by_reference.cpp:116:8:116:13 | pouter | AST only |
| by_reference.cpp:116:16:116:16 | a | AST only |
| by_reference.cpp:122:21:122:25 | outer | AST only |
| by_reference.cpp:122:27:122:38 | inner_nested | AST only |
| by_reference.cpp:123:21:123:36 | * ... | AST only |
| by_reference.cpp:123:22:123:26 | outer | AST only |
| by_reference.cpp:124:15:124:19 | outer | AST only |
| by_reference.cpp:124:21:124:21 | a | AST only |
| by_reference.cpp:126:21:126:26 | pouter | AST only |
| by_reference.cpp:126:29:126:40 | inner_nested | AST only |
| by_reference.cpp:127:21:127:38 | * ... | AST only |
| by_reference.cpp:127:22:127:27 | pouter | AST only |
| by_reference.cpp:128:15:128:20 | pouter | AST only |
| by_reference.cpp:128:23:128:23 | a | AST only |
| by_reference.cpp:130:8:130:12 | outer | AST only |
| by_reference.cpp:130:14:130:25 | inner_nested | AST only |
@@ -305,6 +362,32 @@
| qualifiers.cpp:48:10:48:14 | outer | AST only |
| qualifiers.cpp:48:16:48:20 | inner | AST only |
| qualifiers.cpp:48:23:48:23 | a | AST only |
| realistic.cpp:26:5:26:10 | offset | AST only |
| realistic.cpp:42:20:42:20 | o | AST only |
| realistic.cpp:49:9:49:11 | foo | AST only |
| realistic.cpp:49:20:49:22 | baz | AST only |
| realistic.cpp:53:9:53:11 | foo | AST only |
| realistic.cpp:53:9:53:18 | access to array | AST only |
| realistic.cpp:53:20:53:22 | baz | AST only |
| realistic.cpp:53:25:53:33 | userInput | AST only |
| realistic.cpp:53:35:53:43 | bufferLen | AST only |
| realistic.cpp:54:16:54:18 | foo | AST only |
| realistic.cpp:54:16:54:25 | access to array | AST only |
| realistic.cpp:54:27:54:29 | baz | AST only |
| realistic.cpp:54:32:54:40 | userInput | AST only |
| realistic.cpp:54:42:54:47 | buffer | AST only |
| realistic.cpp:60:16:60:18 | dst | AST only |
| realistic.cpp:61:21:61:23 | foo | AST only |
| realistic.cpp:61:21:61:30 | access to array | AST only |
| realistic.cpp:61:32:61:34 | baz | AST only |
| realistic.cpp:61:37:61:45 | userInput | AST only |
| realistic.cpp:61:47:61:55 | bufferLen | AST only |
| realistic.cpp:65:21:65:23 | foo | AST only |
| realistic.cpp:65:21:65:30 | access to array | AST only |
| realistic.cpp:65:32:65:34 | baz | AST only |
| realistic.cpp:65:37:65:45 | userInput | AST only |
| realistic.cpp:65:47:65:52 | buffer | AST only |
| realistic.cpp:66:21:66:23 | dst | AST only |
| simple.cpp:20:24:20:25 | a_ | AST only |
| simple.cpp:21:24:21:25 | b_ | AST only |
| simple.cpp:28:10:28:10 | f | AST only |
@@ -321,6 +404,7 @@
| simple.cpp:83:9:83:10 | this | AST only |
| simple.cpp:83:12:83:13 | f1 | AST only |
| simple.cpp:84:14:84:20 | this | AST only |
| simple.cpp:92:7:92:7 | i | AST only |
| struct_init.c:15:8:15:9 | ab | AST only |
| struct_init.c:15:12:15:12 | a | AST only |
| struct_init.c:16:8:16:9 | ab | AST only |
@@ -343,6 +427,5 @@
| struct_init.c:34:14:34:22 | pointerAB | AST only |
| struct_init.c:34:25:34:25 | b | AST only |
| struct_init.c:36:10:36:24 | & ... | AST only |
| struct_init.c:36:11:36:15 | outer | AST only |
| struct_init.c:46:10:46:14 | outer | AST only |
| struct_init.c:46:16:46:24 | pointerAB | AST only |

View File

@@ -27,10 +27,28 @@
| aliasing.cpp:86:3:86:3 | s |
| aliasing.cpp:92:5:92:5 | s |
| aliasing.cpp:98:3:98:3 | s |
| aliasing.cpp:111:16:111:16 | s |
| aliasing.cpp:147:16:147:19 | access to array |
| aliasing.cpp:175:19:175:19 | s |
| aliasing.cpp:181:19:181:19 | s |
| aliasing.cpp:187:19:187:19 | s |
| aliasing.cpp:194:19:194:19 | s |
| aliasing.cpp:200:21:200:21 | s |
| aliasing.cpp:205:21:205:21 | s |
| arrays.cpp:6:3:6:5 | arr |
| arrays.cpp:36:3:36:17 | access to array |
| by_reference.cpp:12:5:12:5 | s |
| by_reference.cpp:16:5:16:8 | this |
| by_reference.cpp:84:3:84:7 | inner |
| by_reference.cpp:88:3:88:7 | inner |
| by_reference.cpp:102:22:102:26 | outer |
| by_reference.cpp:104:16:104:20 | outer |
| by_reference.cpp:106:22:106:27 | pouter |
| by_reference.cpp:108:16:108:21 | pouter |
| by_reference.cpp:122:21:122:25 | outer |
| by_reference.cpp:124:15:124:19 | outer |
| by_reference.cpp:126:21:126:26 | pouter |
| by_reference.cpp:128:15:128:20 | pouter |
| complex.cpp:11:22:11:23 | this |
| complex.cpp:12:22:12:23 | this |
| constructors.cpp:20:24:20:25 | this |
@@ -38,7 +56,10 @@
| qualifiers.cpp:9:30:9:33 | this |
| qualifiers.cpp:12:49:12:53 | inner |
| qualifiers.cpp:13:51:13:55 | inner |
| realistic.cpp:49:9:49:18 | access to array |
| simple.cpp:20:24:20:25 | this |
| simple.cpp:21:24:21:25 | this |
| simple.cpp:65:5:65:5 | a |
| simple.cpp:83:9:83:10 | f2 |
| simple.cpp:92:5:92:5 | a |
| struct_init.c:36:11:36:15 | outer |

View File

@@ -187,6 +187,77 @@
| aliasing.cpp:92:7:92:8 | m1 |
| aliasing.cpp:98:3:98:3 | s |
| aliasing.cpp:98:5:98:6 | m1 |
| aliasing.cpp:106:3:106:5 | * ... |
| aliasing.cpp:111:15:111:19 | & ... |
| aliasing.cpp:111:16:111:16 | s |
| aliasing.cpp:121:15:121:16 | xs |
| aliasing.cpp:126:15:126:20 | ... - ... |
| aliasing.cpp:131:15:131:16 | xs |
| aliasing.cpp:136:15:136:17 | + ... |
| aliasing.cpp:141:15:141:15 | s |
| aliasing.cpp:141:17:141:20 | data |
| aliasing.cpp:147:15:147:22 | & ... |
| aliasing.cpp:147:16:147:19 | access to array |
| aliasing.cpp:158:15:158:15 | s |
| aliasing.cpp:158:17:158:20 | data |
| aliasing.cpp:164:15:164:15 | s |
| aliasing.cpp:164:17:164:20 | data |
| aliasing.cpp:175:15:175:22 | & ... |
| aliasing.cpp:175:16:175:17 | s2 |
| aliasing.cpp:175:19:175:19 | s |
| aliasing.cpp:181:15:181:22 | & ... |
| aliasing.cpp:181:16:181:17 | s2 |
| aliasing.cpp:181:19:181:19 | s |
| aliasing.cpp:187:15:187:22 | & ... |
| aliasing.cpp:187:16:187:17 | s2 |
| aliasing.cpp:187:19:187:19 | s |
| aliasing.cpp:194:15:194:22 | & ... |
| aliasing.cpp:194:16:194:17 | s2 |
| aliasing.cpp:194:19:194:19 | s |
| aliasing.cpp:200:15:200:24 | & ... |
| aliasing.cpp:200:16:200:18 | ps2 |
| aliasing.cpp:200:21:200:21 | s |
| aliasing.cpp:205:15:205:24 | & ... |
| aliasing.cpp:205:16:205:18 | ps2 |
| aliasing.cpp:205:21:205:21 | s |
| arrays.cpp:6:3:6:8 | access to array |
| arrays.cpp:15:3:15:10 | * ... |
| arrays.cpp:36:3:36:3 | o |
| arrays.cpp:36:3:36:17 | access to array |
| arrays.cpp:36:5:36:10 | nested |
| arrays.cpp:36:19:36:22 | data |
| arrays.cpp:37:8:37:8 | o |
| arrays.cpp:37:8:37:22 | access to array |
| arrays.cpp:37:10:37:15 | nested |
| arrays.cpp:37:24:37:27 | data |
| arrays.cpp:38:8:38:8 | o |
| arrays.cpp:38:8:38:22 | access to array |
| arrays.cpp:38:10:38:15 | nested |
| arrays.cpp:38:24:38:27 | data |
| arrays.cpp:42:3:42:3 | o |
| arrays.cpp:42:3:42:20 | access to array |
| arrays.cpp:42:5:42:12 | indirect |
| arrays.cpp:42:22:42:25 | data |
| arrays.cpp:43:8:43:8 | o |
| arrays.cpp:43:8:43:25 | access to array |
| arrays.cpp:43:10:43:17 | indirect |
| arrays.cpp:43:27:43:30 | data |
| arrays.cpp:44:8:44:8 | o |
| arrays.cpp:44:8:44:25 | access to array |
| arrays.cpp:44:10:44:17 | indirect |
| arrays.cpp:44:27:44:30 | data |
| arrays.cpp:48:3:48:3 | o |
| arrays.cpp:48:3:48:20 | access to array |
| arrays.cpp:48:5:48:12 | indirect |
| arrays.cpp:48:22:48:25 | data |
| arrays.cpp:49:8:49:8 | o |
| arrays.cpp:49:8:49:25 | access to array |
| arrays.cpp:49:10:49:17 | indirect |
| arrays.cpp:49:27:49:30 | data |
| arrays.cpp:50:8:50:8 | o |
| arrays.cpp:50:8:50:25 | access to array |
| arrays.cpp:50:10:50:17 | indirect |
| arrays.cpp:50:27:50:30 | data |
| by_reference.cpp:12:5:12:5 | s |
| by_reference.cpp:12:8:12:8 | a |
| by_reference.cpp:16:5:16:8 | this |
@@ -211,6 +282,8 @@
| by_reference.cpp:84:10:84:10 | a |
| by_reference.cpp:88:3:88:7 | inner |
| by_reference.cpp:88:9:88:9 | a |
| by_reference.cpp:92:3:92:5 | * ... |
| by_reference.cpp:96:3:96:4 | pa |
| by_reference.cpp:102:21:102:39 | & ... |
| by_reference.cpp:102:22:102:26 | outer |
| by_reference.cpp:103:21:103:25 | outer |
@@ -345,6 +418,33 @@
| qualifiers.cpp:48:10:48:14 | outer |
| qualifiers.cpp:48:16:48:20 | inner |
| qualifiers.cpp:48:23:48:23 | a |
| realistic.cpp:26:5:26:10 | offset |
| realistic.cpp:42:20:42:20 | o |
| realistic.cpp:49:9:49:11 | foo |
| realistic.cpp:49:9:49:18 | access to array |
| realistic.cpp:49:20:49:22 | baz |
| realistic.cpp:53:9:53:11 | foo |
| realistic.cpp:53:9:53:18 | access to array |
| realistic.cpp:53:20:53:22 | baz |
| realistic.cpp:53:25:53:33 | userInput |
| realistic.cpp:53:35:53:43 | bufferLen |
| realistic.cpp:54:16:54:18 | foo |
| realistic.cpp:54:16:54:25 | access to array |
| realistic.cpp:54:27:54:29 | baz |
| realistic.cpp:54:32:54:40 | userInput |
| realistic.cpp:54:42:54:47 | buffer |
| realistic.cpp:60:16:60:18 | dst |
| realistic.cpp:61:21:61:23 | foo |
| realistic.cpp:61:21:61:30 | access to array |
| realistic.cpp:61:32:61:34 | baz |
| realistic.cpp:61:37:61:45 | userInput |
| realistic.cpp:61:47:61:55 | bufferLen |
| realistic.cpp:65:21:65:23 | foo |
| realistic.cpp:65:21:65:30 | access to array |
| realistic.cpp:65:32:65:34 | baz |
| realistic.cpp:65:37:65:45 | userInput |
| realistic.cpp:65:47:65:52 | buffer |
| realistic.cpp:66:21:66:23 | dst |
| simple.cpp:20:24:20:25 | a_ |
| simple.cpp:20:24:20:25 | this |
| simple.cpp:21:24:21:25 | b_ |
@@ -365,6 +465,8 @@
| simple.cpp:83:9:83:10 | this |
| simple.cpp:83:12:83:13 | f1 |
| simple.cpp:84:14:84:20 | this |
| simple.cpp:92:5:92:5 | a |
| simple.cpp:92:7:92:7 | i |
| struct_init.c:15:8:15:9 | ab |
| struct_init.c:15:12:15:12 | a |
| struct_init.c:16:8:16:9 | ab |

View File

@@ -155,6 +155,74 @@ edges
| aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:92:3:92:23 | ... = ... |
| aliasing.cpp:93:8:93:8 | w [s, m1] | aliasing.cpp:93:10:93:10 | s [m1] |
| aliasing.cpp:93:10:93:10 | s [m1] | aliasing.cpp:93:12:93:13 | m1 |
| aliasing.cpp:106:4:106:5 | pa [inner post update] | aliasing.cpp:158:17:158:20 | ref arg data |
| aliasing.cpp:106:4:106:5 | pa [inner post update] | aliasing.cpp:164:17:164:20 | ref arg data |
| aliasing.cpp:106:4:106:5 | pa [inner post update] | aliasing.cpp:175:15:175:22 | ref arg & ... |
| aliasing.cpp:106:4:106:5 | pa [inner post update] | aliasing.cpp:187:15:187:22 | ref arg & ... |
| aliasing.cpp:106:4:106:5 | pa [inner post update] | aliasing.cpp:200:15:200:24 | ref arg & ... |
| aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:106:4:106:5 | pa [inner post update] |
| aliasing.cpp:158:15:158:15 | s [post update] [data] | aliasing.cpp:159:9:159:9 | s [data] |
| aliasing.cpp:158:17:158:20 | ref arg data | aliasing.cpp:158:15:158:15 | s [post update] [data] |
| aliasing.cpp:159:9:159:9 | s [data] | aliasing.cpp:159:11:159:14 | data |
| aliasing.cpp:159:11:159:14 | data | aliasing.cpp:159:8:159:14 | * ... |
| aliasing.cpp:164:15:164:15 | s [post update] [data] | aliasing.cpp:165:8:165:8 | s [data] |
| aliasing.cpp:164:17:164:20 | ref arg data | aliasing.cpp:164:15:164:15 | s [post update] [data] |
| aliasing.cpp:165:8:165:8 | s [data] | aliasing.cpp:165:10:165:13 | data |
| aliasing.cpp:165:10:165:13 | data | aliasing.cpp:165:8:165:16 | access to array |
| aliasing.cpp:175:15:175:22 | ref arg & ... | aliasing.cpp:175:21:175:22 | m1 [inner post update] |
| aliasing.cpp:175:16:175:17 | s2 [post update] [s, m1] | aliasing.cpp:176:8:176:9 | s2 [s, m1] |
| aliasing.cpp:175:19:175:19 | s [post update] [m1] | aliasing.cpp:175:16:175:17 | s2 [post update] [s, m1] |
| aliasing.cpp:175:21:175:22 | m1 [inner post update] | aliasing.cpp:175:19:175:19 | s [post update] [m1] |
| aliasing.cpp:176:8:176:9 | s2 [s, m1] | aliasing.cpp:176:11:176:11 | s [m1] |
| aliasing.cpp:176:11:176:11 | s [m1] | aliasing.cpp:176:13:176:14 | m1 |
| aliasing.cpp:187:15:187:22 | ref arg & ... | aliasing.cpp:187:21:187:22 | m1 [inner post update] |
| aliasing.cpp:187:16:187:17 | s2 [post update] [s, m1] | aliasing.cpp:189:8:189:11 | s2_2 [s, m1] |
| aliasing.cpp:187:19:187:19 | s [post update] [m1] | aliasing.cpp:187:16:187:17 | s2 [post update] [s, m1] |
| aliasing.cpp:187:21:187:22 | m1 [inner post update] | aliasing.cpp:187:19:187:19 | s [post update] [m1] |
| aliasing.cpp:189:8:189:11 | s2_2 [s, m1] | aliasing.cpp:189:13:189:13 | s [m1] |
| aliasing.cpp:189:13:189:13 | s [m1] | aliasing.cpp:189:15:189:16 | m1 |
| aliasing.cpp:200:15:200:24 | ref arg & ... | aliasing.cpp:200:23:200:24 | m1 [inner post update] |
| aliasing.cpp:200:16:200:18 | ps2 [post update] [s, m1] | aliasing.cpp:201:8:201:10 | ps2 [s, m1] |
| aliasing.cpp:200:21:200:21 | s [post update] [m1] | aliasing.cpp:200:16:200:18 | ps2 [post update] [s, m1] |
| aliasing.cpp:200:23:200:24 | m1 [inner post update] | aliasing.cpp:200:21:200:21 | s [post update] [m1] |
| aliasing.cpp:201:8:201:10 | ps2 [s, m1] | aliasing.cpp:201:13:201:13 | s [m1] |
| aliasing.cpp:201:13:201:13 | s [m1] | aliasing.cpp:201:15:201:16 | m1 |
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:7:8:7:13 | access to array |
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:8:8:8:13 | access to array |
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:9:8:9:11 | * ... |
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:10:8:10:15 | * ... |
| arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:16:8:16:13 | access to array |
| arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:17:8:17:13 | access to array |
| arrays.cpp:36:3:36:3 | o [post update] [nested, arr, ... (3)] | arrays.cpp:37:8:37:8 | o [nested, arr, ... (3)] |
| arrays.cpp:36:3:36:3 | o [post update] [nested, arr, ... (3)] | arrays.cpp:38:8:38:8 | o [nested, arr, ... (3)] |
| arrays.cpp:36:3:36:17 | access to array [post update] [data] | arrays.cpp:36:12:36:14 | arr [inner post update] [data] |
| arrays.cpp:36:3:36:37 | ... = ... | arrays.cpp:36:3:36:17 | access to array [post update] [data] |
| arrays.cpp:36:5:36:10 | nested [post update] [arr, data] | arrays.cpp:36:3:36:3 | o [post update] [nested, arr, ... (3)] |
| arrays.cpp:36:12:36:14 | arr [inner post update] [data] | arrays.cpp:36:5:36:10 | nested [post update] [arr, data] |
| arrays.cpp:36:26:36:35 | call to user_input | arrays.cpp:36:3:36:37 | ... = ... |
| arrays.cpp:37:8:37:8 | o [nested, arr, ... (3)] | arrays.cpp:37:10:37:15 | nested [arr, data] |
| arrays.cpp:37:8:37:22 | access to array [data] | arrays.cpp:37:24:37:27 | data |
| arrays.cpp:37:10:37:15 | nested [arr, data] | arrays.cpp:37:17:37:19 | arr [data] |
| arrays.cpp:37:17:37:19 | arr [data] | arrays.cpp:37:8:37:22 | access to array [data] |
| arrays.cpp:38:8:38:8 | o [nested, arr, ... (3)] | arrays.cpp:38:10:38:15 | nested [arr, data] |
| arrays.cpp:38:8:38:22 | access to array [data] | arrays.cpp:38:24:38:27 | data |
| arrays.cpp:38:10:38:15 | nested [arr, data] | arrays.cpp:38:17:38:19 | arr [data] |
| arrays.cpp:38:17:38:19 | arr [data] | arrays.cpp:38:8:38:22 | access to array [data] |
| arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, ... (3)] | arrays.cpp:43:8:43:8 | o [indirect, arr, ... (3)] |
| arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, ... (3)] | arrays.cpp:44:8:44:8 | o [indirect, arr, ... (3)] |
| arrays.cpp:42:3:42:20 | access to array [post update] [data] | arrays.cpp:42:15:42:17 | arr [inner post update] [data] |
| arrays.cpp:42:3:42:40 | ... = ... | arrays.cpp:42:3:42:20 | access to array [post update] [data] |
| arrays.cpp:42:5:42:12 | indirect [post update] [arr, data] | arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, ... (3)] |
| arrays.cpp:42:15:42:17 | arr [inner post update] [data] | arrays.cpp:42:5:42:12 | indirect [post update] [arr, data] |
| arrays.cpp:42:29:42:38 | call to user_input | arrays.cpp:42:3:42:40 | ... = ... |
| arrays.cpp:43:8:43:8 | o [indirect, arr, ... (3)] | arrays.cpp:43:10:43:17 | indirect [arr, data] |
| arrays.cpp:43:8:43:25 | access to array [data] | arrays.cpp:43:27:43:30 | data |
| arrays.cpp:43:10:43:17 | indirect [arr, data] | arrays.cpp:43:20:43:22 | arr [data] |
| arrays.cpp:43:20:43:22 | arr [data] | arrays.cpp:43:8:43:25 | access to array [data] |
| arrays.cpp:44:8:44:8 | o [indirect, arr, ... (3)] | arrays.cpp:44:10:44:17 | indirect [arr, data] |
| arrays.cpp:44:8:44:25 | access to array [data] | arrays.cpp:44:27:44:30 | data |
| arrays.cpp:44:10:44:17 | indirect [arr, data] | arrays.cpp:44:20:44:22 | arr [data] |
| arrays.cpp:44:20:44:22 | arr [data] | arrays.cpp:44:8:44:25 | access to array [data] |
| by_reference.cpp:50:3:50:3 | ref arg s [a] | by_reference.cpp:51:8:51:8 | s [a] |
| by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:50:3:50:3 | ref arg s [a] |
| by_reference.cpp:51:8:51:8 | s [a] | by_reference.cpp:51:10:51:20 | call to getDirectly |
@@ -184,6 +252,9 @@ edges
| by_reference.cpp:88:3:88:7 | inner [post update] [a] | by_reference.cpp:127:21:127:38 | ref arg * ... [a] |
| by_reference.cpp:88:3:88:24 | ... = ... | by_reference.cpp:88:3:88:7 | inner [post update] [a] |
| by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:88:3:88:24 | ... = ... |
| by_reference.cpp:92:4:92:5 | pa [inner post update] | by_reference.cpp:104:15:104:22 | ref arg & ... |
| by_reference.cpp:92:4:92:5 | pa [inner post update] | by_reference.cpp:108:15:108:24 | ref arg & ... |
| by_reference.cpp:92:9:92:18 | call to user_input | by_reference.cpp:92:4:92:5 | pa [inner post update] |
| by_reference.cpp:95:25:95:26 | pa | by_reference.cpp:124:21:124:21 | ref arg a |
| by_reference.cpp:95:25:95:26 | pa | by_reference.cpp:128:23:128:23 | ref arg a |
| by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:95:25:95:26 | pa |
@@ -192,19 +263,27 @@ edges
| by_reference.cpp:102:28:102:39 | inner_nested [inner post update] [a] | by_reference.cpp:102:22:102:26 | outer [post update] [inner_nested, a] |
| by_reference.cpp:103:21:103:25 | outer [post update] [inner_ptr, a] | by_reference.cpp:111:8:111:12 | outer [inner_ptr, a] |
| by_reference.cpp:103:27:103:35 | ref arg inner_ptr [a] | by_reference.cpp:103:21:103:25 | outer [post update] [inner_ptr, a] |
| by_reference.cpp:104:15:104:22 | ref arg & ... | by_reference.cpp:104:22:104:22 | a [inner post update] |
| by_reference.cpp:104:16:104:20 | outer [post update] [a] | by_reference.cpp:112:8:112:12 | outer [a] |
| by_reference.cpp:104:22:104:22 | a [inner post update] | by_reference.cpp:104:16:104:20 | outer [post update] [a] |
| by_reference.cpp:106:21:106:41 | ref arg & ... [a] | by_reference.cpp:106:30:106:41 | inner_nested [inner post update] [a] |
| by_reference.cpp:106:22:106:27 | pouter [post update] [inner_nested, a] | by_reference.cpp:114:8:114:13 | pouter [inner_nested, a] |
| by_reference.cpp:106:30:106:41 | inner_nested [inner post update] [a] | by_reference.cpp:106:22:106:27 | pouter [post update] [inner_nested, a] |
| by_reference.cpp:107:21:107:26 | pouter [post update] [inner_ptr, a] | by_reference.cpp:115:8:115:13 | pouter [inner_ptr, a] |
| by_reference.cpp:107:29:107:37 | ref arg inner_ptr [a] | by_reference.cpp:107:21:107:26 | pouter [post update] [inner_ptr, a] |
| by_reference.cpp:108:15:108:24 | ref arg & ... | by_reference.cpp:108:24:108:24 | a [inner post update] |
| by_reference.cpp:108:16:108:21 | pouter [post update] [a] | by_reference.cpp:116:8:116:13 | pouter [a] |
| by_reference.cpp:108:24:108:24 | a [inner post update] | by_reference.cpp:108:16:108:21 | pouter [post update] [a] |
| by_reference.cpp:110:8:110:12 | outer [inner_nested, a] | by_reference.cpp:110:14:110:25 | inner_nested [a] |
| by_reference.cpp:110:14:110:25 | inner_nested [a] | by_reference.cpp:110:27:110:27 | a |
| by_reference.cpp:111:8:111:12 | outer [inner_ptr, a] | by_reference.cpp:111:14:111:22 | inner_ptr [a] |
| by_reference.cpp:111:14:111:22 | inner_ptr [a] | by_reference.cpp:111:25:111:25 | a |
| by_reference.cpp:112:8:112:12 | outer [a] | by_reference.cpp:112:14:112:14 | a |
| by_reference.cpp:114:8:114:13 | pouter [inner_nested, a] | by_reference.cpp:114:16:114:27 | inner_nested [a] |
| by_reference.cpp:114:16:114:27 | inner_nested [a] | by_reference.cpp:114:29:114:29 | a |
| by_reference.cpp:115:8:115:13 | pouter [inner_ptr, a] | by_reference.cpp:115:16:115:24 | inner_ptr [a] |
| by_reference.cpp:115:16:115:24 | inner_ptr [a] | by_reference.cpp:115:27:115:27 | a |
| by_reference.cpp:116:8:116:13 | pouter [a] | by_reference.cpp:116:16:116:16 | a |
| by_reference.cpp:122:21:122:25 | outer [post update] [inner_nested, a] | by_reference.cpp:130:8:130:12 | outer [inner_nested, a] |
| by_reference.cpp:122:27:122:38 | ref arg inner_nested [a] | by_reference.cpp:122:21:122:25 | outer [post update] [inner_nested, a] |
| by_reference.cpp:123:21:123:36 | ref arg * ... [a] | by_reference.cpp:123:28:123:36 | inner_ptr [inner post update] [a] |
@@ -307,6 +386,18 @@ edges
| qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:47:5:47:42 | ... = ... |
| qualifiers.cpp:48:10:48:14 | outer [inner, a] | qualifiers.cpp:48:16:48:20 | inner [a] |
| qualifiers.cpp:48:16:48:20 | inner [a] | qualifiers.cpp:48:23:48:23 | a |
| realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, ... (4)] | realistic.cpp:61:21:61:23 | foo [bar, baz, ... (4)] |
| realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, ... (3)] | realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, ... (3)] |
| realistic.cpp:53:9:53:66 | ... = ... | realistic.cpp:53:25:53:33 | userInput [post update] [bufferLen] |
| realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, ... (3)] | realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, ... (4)] |
| realistic.cpp:53:20:53:22 | baz [post update] [userInput, bufferLen] | realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, ... (3)] |
| realistic.cpp:53:25:53:33 | userInput [post update] [bufferLen] | realistic.cpp:53:20:53:22 | baz [post update] [userInput, bufferLen] |
| realistic.cpp:53:55:53:64 | call to user_input | realistic.cpp:53:9:53:66 | ... = ... |
| realistic.cpp:61:21:61:23 | foo [bar, baz, ... (4)] | realistic.cpp:61:25:61:27 | bar [baz, userInput, ... (3)] |
| realistic.cpp:61:21:61:30 | access to array [baz, userInput, ... (3)] | realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] |
| realistic.cpp:61:25:61:27 | bar [baz, userInput, ... (3)] | realistic.cpp:61:21:61:30 | access to array [baz, userInput, ... (3)] |
| realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] | realistic.cpp:61:37:61:45 | userInput [bufferLen] |
| realistic.cpp:61:37:61:45 | userInput [bufferLen] | realistic.cpp:61:47:61:55 | bufferLen |
| simple.cpp:26:15:26:15 | f [a_] | simple.cpp:28:10:28:10 | f [a_] |
| simple.cpp:26:15:26:15 | f [b_] | simple.cpp:29:10:29:10 | f [b_] |
| simple.cpp:28:10:28:10 | f [a_] | simple.cpp:28:12:28:12 | call to a |
@@ -332,6 +423,10 @@ edges
| simple.cpp:83:9:83:28 | ... = ... | simple.cpp:83:9:83:10 | f2 [post update] [f1] |
| simple.cpp:83:17:83:26 | call to user_input | simple.cpp:83:9:83:28 | ... = ... |
| simple.cpp:84:14:84:20 | this [f2, f1] | simple.cpp:84:14:84:20 | call to getf2f1 |
| simple.cpp:92:5:92:5 | a [post update] [i] | simple.cpp:94:10:94:11 | a2 [i] |
| simple.cpp:92:5:92:22 | ... = ... | simple.cpp:92:5:92:5 | a [post update] [i] |
| simple.cpp:92:11:92:20 | call to user_input | simple.cpp:92:5:92:22 | ... = ... |
| simple.cpp:94:10:94:11 | a2 [i] | simple.cpp:94:13:94:13 | i |
| struct_init.c:14:24:14:25 | ab [a] | struct_init.c:15:8:15:9 | ab [a] |
| struct_init.c:15:8:15:9 | ab [a] | struct_init.c:15:12:15:12 | a |
| struct_init.c:20:17:20:36 | {...} [a] | struct_init.c:22:8:22:9 | ab [a] |
@@ -539,6 +634,79 @@ nodes
| aliasing.cpp:93:8:93:8 | w [s, m1] | semmle.label | w [s, m1] |
| aliasing.cpp:93:10:93:10 | s [m1] | semmle.label | s [m1] |
| aliasing.cpp:93:12:93:13 | m1 | semmle.label | m1 |
| aliasing.cpp:106:4:106:5 | pa [inner post update] | semmle.label | pa [inner post update] |
| aliasing.cpp:106:9:106:18 | call to user_input | semmle.label | call to user_input |
| aliasing.cpp:158:15:158:15 | s [post update] [data] | semmle.label | s [post update] [data] |
| aliasing.cpp:158:17:158:20 | ref arg data | semmle.label | ref arg data |
| aliasing.cpp:159:8:159:14 | * ... | semmle.label | * ... |
| aliasing.cpp:159:9:159:9 | s [data] | semmle.label | s [data] |
| aliasing.cpp:159:11:159:14 | data | semmle.label | data |
| aliasing.cpp:164:15:164:15 | s [post update] [data] | semmle.label | s [post update] [data] |
| aliasing.cpp:164:17:164:20 | ref arg data | semmle.label | ref arg data |
| aliasing.cpp:165:8:165:8 | s [data] | semmle.label | s [data] |
| aliasing.cpp:165:8:165:16 | access to array | semmle.label | access to array |
| aliasing.cpp:165:10:165:13 | data | semmle.label | data |
| aliasing.cpp:175:15:175:22 | ref arg & ... | semmle.label | ref arg & ... |
| aliasing.cpp:175:16:175:17 | s2 [post update] [s, m1] | semmle.label | s2 [post update] [s, m1] |
| aliasing.cpp:175:19:175:19 | s [post update] [m1] | semmle.label | s [post update] [m1] |
| aliasing.cpp:175:21:175:22 | m1 [inner post update] | semmle.label | m1 [inner post update] |
| aliasing.cpp:176:8:176:9 | s2 [s, m1] | semmle.label | s2 [s, m1] |
| aliasing.cpp:176:11:176:11 | s [m1] | semmle.label | s [m1] |
| aliasing.cpp:176:13:176:14 | m1 | semmle.label | m1 |
| aliasing.cpp:187:15:187:22 | ref arg & ... | semmle.label | ref arg & ... |
| aliasing.cpp:187:16:187:17 | s2 [post update] [s, m1] | semmle.label | s2 [post update] [s, m1] |
| aliasing.cpp:187:19:187:19 | s [post update] [m1] | semmle.label | s [post update] [m1] |
| aliasing.cpp:187:21:187:22 | m1 [inner post update] | semmle.label | m1 [inner post update] |
| aliasing.cpp:189:8:189:11 | s2_2 [s, m1] | semmle.label | s2_2 [s, m1] |
| aliasing.cpp:189:13:189:13 | s [m1] | semmle.label | s [m1] |
| aliasing.cpp:189:15:189:16 | m1 | semmle.label | m1 |
| aliasing.cpp:200:15:200:24 | ref arg & ... | semmle.label | ref arg & ... |
| aliasing.cpp:200:16:200:18 | ps2 [post update] [s, m1] | semmle.label | ps2 [post update] [s, m1] |
| aliasing.cpp:200:21:200:21 | s [post update] [m1] | semmle.label | s [post update] [m1] |
| aliasing.cpp:200:23:200:24 | m1 [inner post update] | semmle.label | m1 [inner post update] |
| aliasing.cpp:201:8:201:10 | ps2 [s, m1] | semmle.label | ps2 [s, m1] |
| aliasing.cpp:201:13:201:13 | s [m1] | semmle.label | s [m1] |
| aliasing.cpp:201:15:201:16 | m1 | semmle.label | m1 |
| arrays.cpp:6:12:6:21 | call to user_input | semmle.label | call to user_input |
| arrays.cpp:7:8:7:13 | access to array | semmle.label | access to array |
| arrays.cpp:8:8:8:13 | access to array | semmle.label | access to array |
| arrays.cpp:9:8:9:11 | * ... | semmle.label | * ... |
| arrays.cpp:10:8:10:15 | * ... | semmle.label | * ... |
| arrays.cpp:15:14:15:23 | call to user_input | semmle.label | call to user_input |
| arrays.cpp:16:8:16:13 | access to array | semmle.label | access to array |
| arrays.cpp:17:8:17:13 | access to array | semmle.label | access to array |
| arrays.cpp:36:3:36:3 | o [post update] [nested, arr, ... (3)] | semmle.label | o [post update] [nested, arr, ... (3)] |
| arrays.cpp:36:3:36:17 | access to array [post update] [data] | semmle.label | access to array [post update] [data] |
| arrays.cpp:36:3:36:37 | ... = ... | semmle.label | ... = ... |
| arrays.cpp:36:5:36:10 | nested [post update] [arr, data] | semmle.label | nested [post update] [arr, data] |
| arrays.cpp:36:12:36:14 | arr [inner post update] [data] | semmle.label | arr [inner post update] [data] |
| arrays.cpp:36:26:36:35 | call to user_input | semmle.label | call to user_input |
| arrays.cpp:37:8:37:8 | o [nested, arr, ... (3)] | semmle.label | o [nested, arr, ... (3)] |
| arrays.cpp:37:8:37:22 | access to array [data] | semmle.label | access to array [data] |
| arrays.cpp:37:10:37:15 | nested [arr, data] | semmle.label | nested [arr, data] |
| arrays.cpp:37:17:37:19 | arr [data] | semmle.label | arr [data] |
| arrays.cpp:37:24:37:27 | data | semmle.label | data |
| arrays.cpp:38:8:38:8 | o [nested, arr, ... (3)] | semmle.label | o [nested, arr, ... (3)] |
| arrays.cpp:38:8:38:22 | access to array [data] | semmle.label | access to array [data] |
| arrays.cpp:38:10:38:15 | nested [arr, data] | semmle.label | nested [arr, data] |
| arrays.cpp:38:17:38:19 | arr [data] | semmle.label | arr [data] |
| arrays.cpp:38:24:38:27 | data | semmle.label | data |
| arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, ... (3)] | semmle.label | o [post update] [indirect, arr, ... (3)] |
| arrays.cpp:42:3:42:20 | access to array [post update] [data] | semmle.label | access to array [post update] [data] |
| arrays.cpp:42:3:42:40 | ... = ... | semmle.label | ... = ... |
| arrays.cpp:42:5:42:12 | indirect [post update] [arr, data] | semmle.label | indirect [post update] [arr, data] |
| arrays.cpp:42:15:42:17 | arr [inner post update] [data] | semmle.label | arr [inner post update] [data] |
| arrays.cpp:42:29:42:38 | call to user_input | semmle.label | call to user_input |
| arrays.cpp:43:8:43:8 | o [indirect, arr, ... (3)] | semmle.label | o [indirect, arr, ... (3)] |
| arrays.cpp:43:8:43:25 | access to array [data] | semmle.label | access to array [data] |
| arrays.cpp:43:10:43:17 | indirect [arr, data] | semmle.label | indirect [arr, data] |
| arrays.cpp:43:20:43:22 | arr [data] | semmle.label | arr [data] |
| arrays.cpp:43:27:43:30 | data | semmle.label | data |
| arrays.cpp:44:8:44:8 | o [indirect, arr, ... (3)] | semmle.label | o [indirect, arr, ... (3)] |
| arrays.cpp:44:8:44:25 | access to array [data] | semmle.label | access to array [data] |
| arrays.cpp:44:10:44:17 | indirect [arr, data] | semmle.label | indirect [arr, data] |
| arrays.cpp:44:20:44:22 | arr [data] | semmle.label | arr [data] |
| arrays.cpp:44:27:44:30 | data | semmle.label | data |
| by_reference.cpp:50:3:50:3 | ref arg s [a] | semmle.label | ref arg s [a] |
| by_reference.cpp:50:17:50:26 | call to user_input | semmle.label | call to user_input |
| by_reference.cpp:51:8:51:8 | s [a] | semmle.label | s [a] |
@@ -562,6 +730,8 @@ nodes
| by_reference.cpp:88:3:88:7 | inner [post update] [a] | semmle.label | inner [post update] [a] |
| by_reference.cpp:88:3:88:24 | ... = ... | semmle.label | ... = ... |
| by_reference.cpp:88:13:88:22 | call to user_input | semmle.label | call to user_input |
| by_reference.cpp:92:4:92:5 | pa [inner post update] | semmle.label | pa [inner post update] |
| by_reference.cpp:92:9:92:18 | call to user_input | semmle.label | call to user_input |
| by_reference.cpp:95:25:95:26 | pa | semmle.label | pa |
| by_reference.cpp:96:8:96:17 | call to user_input | semmle.label | call to user_input |
| by_reference.cpp:102:21:102:39 | ref arg & ... [a] | semmle.label | ref arg & ... [a] |
@@ -569,23 +739,33 @@ nodes
| by_reference.cpp:102:28:102:39 | inner_nested [inner post update] [a] | semmle.label | inner_nested [inner post update] [a] |
| by_reference.cpp:103:21:103:25 | outer [post update] [inner_ptr, a] | semmle.label | outer [post update] [inner_ptr, a] |
| by_reference.cpp:103:27:103:35 | ref arg inner_ptr [a] | semmle.label | ref arg inner_ptr [a] |
| by_reference.cpp:104:15:104:22 | ref arg & ... | semmle.label | ref arg & ... |
| by_reference.cpp:104:16:104:20 | outer [post update] [a] | semmle.label | outer [post update] [a] |
| by_reference.cpp:104:22:104:22 | a [inner post update] | semmle.label | a [inner post update] |
| by_reference.cpp:106:21:106:41 | ref arg & ... [a] | semmle.label | ref arg & ... [a] |
| by_reference.cpp:106:22:106:27 | pouter [post update] [inner_nested, a] | semmle.label | pouter [post update] [inner_nested, a] |
| by_reference.cpp:106:30:106:41 | inner_nested [inner post update] [a] | semmle.label | inner_nested [inner post update] [a] |
| by_reference.cpp:107:21:107:26 | pouter [post update] [inner_ptr, a] | semmle.label | pouter [post update] [inner_ptr, a] |
| by_reference.cpp:107:29:107:37 | ref arg inner_ptr [a] | semmle.label | ref arg inner_ptr [a] |
| by_reference.cpp:108:15:108:24 | ref arg & ... | semmle.label | ref arg & ... |
| by_reference.cpp:108:16:108:21 | pouter [post update] [a] | semmle.label | pouter [post update] [a] |
| by_reference.cpp:108:24:108:24 | a [inner post update] | semmle.label | a [inner post update] |
| by_reference.cpp:110:8:110:12 | outer [inner_nested, a] | semmle.label | outer [inner_nested, a] |
| by_reference.cpp:110:14:110:25 | inner_nested [a] | semmle.label | inner_nested [a] |
| by_reference.cpp:110:27:110:27 | a | semmle.label | a |
| by_reference.cpp:111:8:111:12 | outer [inner_ptr, a] | semmle.label | outer [inner_ptr, a] |
| by_reference.cpp:111:14:111:22 | inner_ptr [a] | semmle.label | inner_ptr [a] |
| by_reference.cpp:111:25:111:25 | a | semmle.label | a |
| by_reference.cpp:112:8:112:12 | outer [a] | semmle.label | outer [a] |
| by_reference.cpp:112:14:112:14 | a | semmle.label | a |
| by_reference.cpp:114:8:114:13 | pouter [inner_nested, a] | semmle.label | pouter [inner_nested, a] |
| by_reference.cpp:114:16:114:27 | inner_nested [a] | semmle.label | inner_nested [a] |
| by_reference.cpp:114:29:114:29 | a | semmle.label | a |
| by_reference.cpp:115:8:115:13 | pouter [inner_ptr, a] | semmle.label | pouter [inner_ptr, a] |
| by_reference.cpp:115:16:115:24 | inner_ptr [a] | semmle.label | inner_ptr [a] |
| by_reference.cpp:115:27:115:27 | a | semmle.label | a |
| by_reference.cpp:116:8:116:13 | pouter [a] | semmle.label | pouter [a] |
| by_reference.cpp:116:16:116:16 | a | semmle.label | a |
| by_reference.cpp:122:21:122:25 | outer [post update] [inner_nested, a] | semmle.label | outer [post update] [inner_nested, a] |
| by_reference.cpp:122:27:122:38 | ref arg inner_nested [a] | semmle.label | ref arg inner_nested [a] |
| by_reference.cpp:123:21:123:36 | ref arg * ... [a] | semmle.label | ref arg * ... [a] |
@@ -703,6 +883,19 @@ nodes
| qualifiers.cpp:48:10:48:14 | outer [inner, a] | semmle.label | outer [inner, a] |
| qualifiers.cpp:48:16:48:20 | inner [a] | semmle.label | inner [a] |
| qualifiers.cpp:48:23:48:23 | a | semmle.label | a |
| realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, ... (4)] | semmle.label | foo [post update] [bar, baz, ... (4)] |
| realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, ... (3)] | semmle.label | access to array [post update] [baz, userInput, ... (3)] |
| realistic.cpp:53:9:53:66 | ... = ... | semmle.label | ... = ... |
| realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, ... (3)] | semmle.label | bar [inner post update] [baz, userInput, ... (3)] |
| realistic.cpp:53:20:53:22 | baz [post update] [userInput, bufferLen] | semmle.label | baz [post update] [userInput, bufferLen] |
| realistic.cpp:53:25:53:33 | userInput [post update] [bufferLen] | semmle.label | userInput [post update] [bufferLen] |
| realistic.cpp:53:55:53:64 | call to user_input | semmle.label | call to user_input |
| realistic.cpp:61:21:61:23 | foo [bar, baz, ... (4)] | semmle.label | foo [bar, baz, ... (4)] |
| realistic.cpp:61:21:61:30 | access to array [baz, userInput, ... (3)] | semmle.label | access to array [baz, userInput, ... (3)] |
| realistic.cpp:61:25:61:27 | bar [baz, userInput, ... (3)] | semmle.label | bar [baz, userInput, ... (3)] |
| realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] | semmle.label | baz [userInput, bufferLen] |
| realistic.cpp:61:37:61:45 | userInput [bufferLen] | semmle.label | userInput [bufferLen] |
| realistic.cpp:61:47:61:55 | bufferLen | semmle.label | bufferLen |
| simple.cpp:26:15:26:15 | f [a_] | semmle.label | f [a_] |
| simple.cpp:26:15:26:15 | f [b_] | semmle.label | f [b_] |
| simple.cpp:28:10:28:10 | f [a_] | semmle.label | f [a_] |
@@ -732,6 +925,11 @@ nodes
| simple.cpp:83:17:83:26 | call to user_input | semmle.label | call to user_input |
| simple.cpp:84:14:84:20 | call to getf2f1 | semmle.label | call to getf2f1 |
| simple.cpp:84:14:84:20 | this [f2, f1] | semmle.label | this [f2, f1] |
| simple.cpp:92:5:92:5 | a [post update] [i] | semmle.label | a [post update] [i] |
| simple.cpp:92:5:92:22 | ... = ... | semmle.label | ... = ... |
| simple.cpp:92:11:92:20 | call to user_input | semmle.label | call to user_input |
| simple.cpp:94:10:94:11 | a2 [i] | semmle.label | a2 [i] |
| simple.cpp:94:13:94:13 | i | semmle.label | i |
| struct_init.c:14:24:14:25 | ab [a] | semmle.label | ab [a] |
| struct_init.c:15:8:15:9 | ab [a] | semmle.label | ab [a] |
| struct_init.c:15:12:15:12 | a | semmle.label | a |
@@ -792,14 +990,31 @@ nodes
| aliasing.cpp:30:11:30:12 | m1 | aliasing.cpp:13:10:13:19 | call to user_input | aliasing.cpp:30:11:30:12 | m1 | m1 flows from $@ | aliasing.cpp:13:10:13:19 | call to user_input | call to user_input |
| aliasing.cpp:62:14:62:15 | m1 | aliasing.cpp:60:11:60:20 | call to user_input | aliasing.cpp:62:14:62:15 | m1 | m1 flows from $@ | aliasing.cpp:60:11:60:20 | call to user_input | call to user_input |
| aliasing.cpp:93:12:93:13 | m1 | aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:93:12:93:13 | m1 | m1 flows from $@ | aliasing.cpp:92:12:92:21 | call to user_input | call to user_input |
| aliasing.cpp:159:8:159:14 | * ... | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:159:8:159:14 | * ... | * ... flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
| aliasing.cpp:165:8:165:16 | access to array | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:165:8:165:16 | access to array | access to array flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
| aliasing.cpp:176:13:176:14 | m1 | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:176:13:176:14 | m1 | m1 flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
| aliasing.cpp:189:15:189:16 | m1 | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:189:15:189:16 | m1 | m1 flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
| aliasing.cpp:201:15:201:16 | m1 | aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:201:15:201:16 | m1 | m1 flows from $@ | aliasing.cpp:106:9:106:18 | call to user_input | call to user_input |
| arrays.cpp:7:8:7:13 | access to array | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:7:8:7:13 | access to array | access to array flows from $@ | arrays.cpp:6:12:6:21 | call to user_input | call to user_input |
| arrays.cpp:8:8:8:13 | access to array | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:8:8:8:13 | access to array | access to array flows from $@ | arrays.cpp:6:12:6:21 | call to user_input | call to user_input |
| arrays.cpp:9:8:9:11 | * ... | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:9:8:9:11 | * ... | * ... flows from $@ | arrays.cpp:6:12:6:21 | call to user_input | call to user_input |
| arrays.cpp:10:8:10:15 | * ... | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:10:8:10:15 | * ... | * ... flows from $@ | arrays.cpp:6:12:6:21 | call to user_input | call to user_input |
| arrays.cpp:16:8:16:13 | access to array | arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:16:8:16:13 | access to array | access to array flows from $@ | arrays.cpp:15:14:15:23 | call to user_input | call to user_input |
| arrays.cpp:17:8:17:13 | access to array | arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:17:8:17:13 | access to array | access to array flows from $@ | arrays.cpp:15:14:15:23 | call to user_input | call to user_input |
| arrays.cpp:37:24:37:27 | data | arrays.cpp:36:26:36:35 | call to user_input | arrays.cpp:37:24:37:27 | data | data flows from $@ | arrays.cpp:36:26:36:35 | call to user_input | call to user_input |
| arrays.cpp:38:24:38:27 | data | arrays.cpp:36:26:36:35 | call to user_input | arrays.cpp:38:24:38:27 | data | data flows from $@ | arrays.cpp:36:26:36:35 | call to user_input | call to user_input |
| arrays.cpp:43:27:43:30 | data | arrays.cpp:42:29:42:38 | call to user_input | arrays.cpp:43:27:43:30 | data | data flows from $@ | arrays.cpp:42:29:42:38 | call to user_input | call to user_input |
| arrays.cpp:44:27:44:30 | data | arrays.cpp:42:29:42:38 | call to user_input | arrays.cpp:44:27:44:30 | data | data flows from $@ | arrays.cpp:42:29:42:38 | call to user_input | call to user_input |
| by_reference.cpp:51:10:51:20 | call to getDirectly | by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:51:10:51:20 | call to getDirectly | call to getDirectly flows from $@ | by_reference.cpp:50:17:50:26 | call to user_input | call to user_input |
| by_reference.cpp:57:10:57:22 | call to getIndirectly | by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:57:10:57:22 | call to getIndirectly | call to getIndirectly flows from $@ | by_reference.cpp:56:19:56:28 | call to user_input | call to user_input |
| by_reference.cpp:63:10:63:28 | call to getThroughNonMember | by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:63:10:63:28 | call to getThroughNonMember | call to getThroughNonMember flows from $@ | by_reference.cpp:62:25:62:34 | call to user_input | call to user_input |
| by_reference.cpp:69:8:69:20 | call to nonMemberGetA | by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:69:8:69:20 | call to nonMemberGetA | call to nonMemberGetA flows from $@ | by_reference.cpp:68:21:68:30 | call to user_input | call to user_input |
| by_reference.cpp:110:27:110:27 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:110:27:110:27 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
| by_reference.cpp:111:25:111:25 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:111:25:111:25 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
| by_reference.cpp:112:14:112:14 | a | by_reference.cpp:92:9:92:18 | call to user_input | by_reference.cpp:112:14:112:14 | a | a flows from $@ | by_reference.cpp:92:9:92:18 | call to user_input | call to user_input |
| by_reference.cpp:114:29:114:29 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:114:29:114:29 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
| by_reference.cpp:115:27:115:27 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:115:27:115:27 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
| by_reference.cpp:116:16:116:16 | a | by_reference.cpp:92:9:92:18 | call to user_input | by_reference.cpp:116:16:116:16 | a | a flows from $@ | by_reference.cpp:92:9:92:18 | call to user_input | call to user_input |
| by_reference.cpp:130:27:130:27 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:130:27:130:27 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
| by_reference.cpp:131:25:131:25 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:131:25:131:25 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
| by_reference.cpp:132:14:132:14 | a | by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:132:14:132:14 | a | a flows from $@ | by_reference.cpp:96:8:96:17 | call to user_input | call to user_input |
@@ -824,12 +1039,14 @@ nodes
| qualifiers.cpp:38:23:38:23 | a | qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:38:23:38:23 | a | a flows from $@ | qualifiers.cpp:37:38:37:47 | call to user_input | call to user_input |
| qualifiers.cpp:43:23:43:23 | a | qualifiers.cpp:42:29:42:38 | call to user_input | qualifiers.cpp:43:23:43:23 | a | a flows from $@ | qualifiers.cpp:42:29:42:38 | call to user_input | call to user_input |
| qualifiers.cpp:48:23:48:23 | a | qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:48:23:48:23 | a | a flows from $@ | qualifiers.cpp:47:31:47:40 | call to user_input | call to user_input |
| realistic.cpp:61:47:61:55 | bufferLen | realistic.cpp:53:55:53:64 | call to user_input | realistic.cpp:61:47:61:55 | bufferLen | bufferLen flows from $@ | realistic.cpp:53:55:53:64 | call to user_input | call to user_input |
| simple.cpp:28:12:28:12 | call to a | simple.cpp:39:12:39:21 | call to user_input | simple.cpp:28:12:28:12 | call to a | call to a flows from $@ | simple.cpp:39:12:39:21 | call to user_input | call to user_input |
| simple.cpp:28:12:28:12 | call to a | simple.cpp:41:12:41:21 | call to user_input | simple.cpp:28:12:28:12 | call to a | call to a flows from $@ | simple.cpp:41:12:41:21 | call to user_input | call to user_input |
| simple.cpp:29:12:29:12 | call to b | simple.cpp:40:12:40:21 | call to user_input | simple.cpp:29:12:29:12 | call to b | call to b flows from $@ | simple.cpp:40:12:40:21 | call to user_input | call to user_input |
| simple.cpp:29:12:29:12 | call to b | simple.cpp:42:12:42:21 | call to user_input | simple.cpp:29:12:29:12 | call to b | call to b flows from $@ | simple.cpp:42:12:42:21 | call to user_input | call to user_input |
| simple.cpp:67:13:67:13 | i | simple.cpp:65:11:65:20 | call to user_input | simple.cpp:67:13:67:13 | i | i flows from $@ | simple.cpp:65:11:65:20 | call to user_input | call to user_input |
| simple.cpp:84:14:84:20 | call to getf2f1 | simple.cpp:83:17:83:26 | call to user_input | simple.cpp:84:14:84:20 | call to getf2f1 | call to getf2f1 flows from $@ | simple.cpp:83:17:83:26 | call to user_input | call to user_input |
| simple.cpp:94:13:94:13 | i | simple.cpp:92:11:92:20 | call to user_input | simple.cpp:94:13:94:13 | i | i flows from $@ | simple.cpp:92:11:92:20 | call to user_input | call to user_input |
| struct_init.c:15:12:15:12 | a | struct_init.c:20:20:20:29 | call to user_input | struct_init.c:15:12:15:12 | a | a flows from $@ | struct_init.c:20:20:20:29 | call to user_input | call to user_input |
| struct_init.c:15:12:15:12 | a | struct_init.c:27:7:27:16 | call to user_input | struct_init.c:15:12:15:12 | a | a flows from $@ | struct_init.c:27:7:27:16 | call to user_input | call to user_input |
| struct_init.c:15:12:15:12 | a | struct_init.c:40:20:40:29 | call to user_input | struct_init.c:15:12:15:12 | a | a flows from $@ | struct_init.c:40:20:40:29 | call to user_input | call to user_input |

View File

@@ -0,0 +1,70 @@
typedef unsigned char u8;
typedef unsigned long size_t;
struct UserInput {
size_t bufferLen;
u8 buffer[256];
};
struct Baz {
int foo;
struct UserInput userInput;
};
struct Bar {
u8* foo;
struct Baz * baz;
};
struct Foo {
struct Bar bar[128];
};
void printf(const char *fmt, ...) {
return;
}
void * malloc(size_t size) {
static unsigned char buffer[0x1000];
static unsigned int offset;
if (size + offset >= sizeof(buffer)) return nullptr;
void* m = (void*)&buffer[offset];
offset += size;
return m;
}
void * memcpy ( void * destination, const void * source, size_t num ) {
u8* d = (u8*)destination;
u8* s = (u8*)source;
u8* e = d + num;
while(d != e) {
*d++ = *s++;
}
return destination;
}
void *user_input(void) {
return (void*)"\x0a\x00\x00\x00\x00\x00\x00\x00The quick brown fox jumps over the lazy dog";
}
void sink(void *o) {
printf("%p\n", o);
}
#define MAX_BAZ 3
int main(int argc, char** argv) {
char dst[256];
struct Foo foo;
for (int i = 0; i < MAX_BAZ; i++) {
foo.bar[i].baz = (struct Baz*)malloc(sizeof(struct Baz));
}
int i = 0;
while(i < MAX_BAZ) {
foo.bar[i].baz->userInput.bufferLen = (size_t)user_input();
memcpy(foo.bar[i].baz->userInput.buffer, user_input(), sizeof(foo.bar[i].baz->userInput.buffer));
if(foo.bar[i].baz->userInput.bufferLen > sizeof(foo.bar[i].baz->userInput.buffer))
{
printf("The user-supplied input 0x%lx is larger than the buffer 0x%lx!\n", foo.bar[i].baz->userInput.bufferLen, sizeof(foo.bar[i].baz->userInput.buffer));
return -1;
}
memcpy(dst, foo.bar[i].baz->userInput.buffer, foo.bar[i].baz->userInput.bufferLen);
sink((void*)foo.bar[i].baz->userInput.bufferLen); // $ast $f-:ir
// There is no flow to the following two `sink` calls because the
// source is the _pointer_ returned by `user_input` rather than the
// _data_ to which it points.
sink((void*)foo.bar[i].baz->userInput.buffer); // $f-:ast,ir
sink((void*)dst); // $f-:ast,ir
i++;
}
return 0;
}

View File

@@ -85,4 +85,13 @@ struct C2
}
};
typedef A A_typedef;
void single_field_test_typedef(A_typedef a)
{
a.i = user_input();
A_typedef a2 = a;
sink(a2.i); //$ast,ir
}
} // namespace Simple

View File

@@ -1,4 +1,5 @@
import cpp
import semmle.code.cpp.ir.IR
import semmle.code.cpp.ir.dataflow.TaintTracking
/** Common data flow configuration to be used by tests. */
@@ -6,7 +7,7 @@ class TestAllocationConfig extends TaintTracking::Configuration {
TestAllocationConfig() { this = "TestAllocationConfig" }
override predicate isSource(DataFlow::Node source) {
source.asExpr().(FunctionCall).getTarget().getName() = "source"
source.(DataFlow::ExprNode).getConvertedExpr().(FunctionCall).getTarget().getName() = "source"
or
source.asParameter().getName().matches("source%")
or
@@ -17,8 +18,20 @@ class TestAllocationConfig extends TaintTracking::Configuration {
override predicate isSink(DataFlow::Node sink) {
exists(FunctionCall call |
call.getTarget().getName() = "sink" and
sink.asExpr() = call.getAnArgument()
sink.(DataFlow::ExprNode).getConvertedExpr() = call.getAnArgument()
or
call.getTarget().getName() = "sink" and
sink.asExpr() = call.getAnArgument() and
sink.(DataFlow::ExprNode).getConvertedExpr() instanceof ReferenceDereferenceExpr
)
or
sink
.asInstruction()
.(ReadSideEffectInstruction)
.getPrimaryInstruction()
.(CallInstruction)
.getStaticCallTarget()
.hasName("sink")
}
override predicate isSanitizer(DataFlow::Node barrier) {

View File

@@ -14,7 +14,7 @@ void test_pointer_deref_assignment()
*p_x = source();
sink(x); // tainted [DETECTED BY IR ONLY]
sink(*p_x); // tainted [DETECTED BY IR ONLY]
sink(*p_x); // tainted
sink(*p2_x); // tainted [DETECTED BY IR ONLY]
sink(r_x); // tainted [DETECTED BY IR ONLY]
}
@@ -137,11 +137,11 @@ void test_array_reference_assignment()
ptr2 = &(arr2[5]);
*ptr2 = source();
sink(*ptr2); // tainted [DETECTED BY IR ONLY]
sink(*ptr2); // tainted
sink(arr2[5]); // tainted [DETECTED BY IR ONLY]
ptr3 = arr3;
ptr3[5] = source();
sink(ptr3[5]); // tainted [DETECTED BY IR ONLY]
sink(ptr3[5]); // tainted
sink(arr3[5]); // tainted [DETECTED BY IR ONLY]
}

View File

@@ -144,12 +144,18 @@ namespace std
basic_istream<charT, traits>& read (char_type* s, streamsize n);
streamsize readsome(char_type* s, streamsize n);
basic_istream<charT, traits>& putback(char_type c);
basic_istream<charT,traits>& unget();
};
basic_istream<charT,traits>& getline(char_type* s, streamsize n);
basic_istream<charT,traits>& getline(char_type* s, streamsize n, char_type delim);
};
template<class charT, class traits> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>&, charT*);
template<class charT, class traits, class Allocator> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
template<class charT, class traits, class Allocator> basic_istream<charT,traits>& getline(basic_istream<charT,traits>& is, basic_string<charT,traits,Allocator>& str, charT delim);
template<class charT, class traits, class Allocator> basic_istream<charT,traits>& getline(basic_istream<charT,traits>& is, basic_string<charT,traits,Allocator>& str);
template <class charT, class traits = char_traits<charT> >
class basic_ostream /*: virtual public basic_ios<charT,traits> - not needed for this test */ {
public:
@@ -159,6 +165,7 @@ namespace std
basic_ostream<charT, traits>& put(char_type c);
basic_ostream<charT, traits>& write(const char_type* s, streamsize n);
basic_ostream<charT,traits>& flush();
};
template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const charT*);
@@ -185,6 +192,11 @@ namespace std
void str(const basic_string<charT, traits, Allocator>& str);
};
typedef basic_istream<char> istream;
typedef basic_ostream<char> ostream;
extern istream cin;
extern ostream cout;
using stringstream = basic_stringstream<char>;
}

View File

@@ -14,10 +14,10 @@ char *user_input() {
return source();
}
void sink(const char *s) {};
void sink(const std::string &s) {};
void sink(const char *s);
void sink(const std::string &s);
void sink(const char *filename, const char *mode);
void sink(char) {}
void sink(char);
void test_string()
{

View File

@@ -10,18 +10,18 @@ namespace ns_char
char source();
}
void sink(int i) {};
void sink(int i);
void sink(const std::string &s) {};
void sink(const std::string &s);
template<class charT>
void sink(const std::basic_ostream<charT> &s) {};
void sink(const std::basic_ostream<charT> &s);
template<class charT>
void sink(const std::basic_istream<charT> &s) {};
void sink(const std::basic_istream<charT> &s);
template<class charT>
void sink(const std::basic_iostream<charT> &s) {};
void sink(const std::basic_iostream<charT> &s);
void test_stringstream_string(int amount)
{
@@ -75,14 +75,14 @@ void test_stringstream_int(int source)
sink(ss1 << 1234);
sink(ss2 << source); // tainted
sink(ss1 >> v1);
sink(ss2 >> v2); // tainted [NOT DETECTED]
sink(ss2 >> v2); // tainted
sink(ss1);
sink(ss2); // tainted
sink(ss1.str());
sink(ss2.str()); // tainted
sink(v1);
sink(v2); // tainted [NOT DETECTED]
sink(v2); // tainted
}
void test_stringstream_constructors()
@@ -117,9 +117,9 @@ void test_stringstream_swap()
ss1.swap(ss2);
ss4.swap(ss3);
sink(ss1); // tainted [NOT DETECTED]
sink(ss1); // tainted
sink(ss2); // [FALSE POSITIVE]
sink(ss3); // tainted [NOT DETECTED]
sink(ss3); // tainted
sink(ss4); // [FALSE POSITIVE]
}
@@ -143,46 +143,46 @@ void test_stringstream_in()
sink(ss2 << source()); // tainted
sink(ss1 >> s1);
sink(ss2 >> s2); // tainted [NOT DETECTED]
sink(ss2 >> s3 >> s4); // tainted [NOT DETECTED]
sink(ss2 >> s2); // tainted
sink(ss2 >> s3 >> s4); // tainted
sink(s1);
sink(s2); // tainted [NOT DETECTED]
sink(s3); // tainted [NOT DETECTED]
sink(s4); // tainted [NOT DETECTED]
sink(s2); // tainted
sink(s3); // tainted
sink(s4); // tainted
sink(ss1 >> b1);
sink(ss2 >> b2);
sink(ss2 >> b3 >> b4);
sink(ss2 >> b2); // tainted
sink(ss2 >> b3 >> b4); // tainted
sink(b1);
sink(b2); // tainted [NOT DETECTED]
sink(b3); // tainted [NOT DETECTED]
sink(b4); // tainted [NOT DETECTED]
sink(b2); // tainted
sink(b3); // tainted
sink(b4); // tainted
sink(ss1.read(b5, 100));
sink(ss2.read(b6, 100)); // tainted [NOT DETECTED]
sink(ss2.read(b6, 100)); // tainted
sink(ss1.readsome(b7, 100));
sink(ss2.readsome(b8, 100)); // (returns a length, not significantly tainted)
sink(ss1.get(b9, 100));
sink(ss2.get(b10, 100));
sink(ss2.get(b10, 100)); // tainted
sink(b5);
sink(b6); // tainted [NOT DETECTED]
sink(b6); // tainted
sink(b7);
sink(b8); // tainted [NOT DETECTED]
sink(b8); // tainted
sink(b9);
sink(b10); // tainted [NOT DETECTED]
sink(b10); // tainted
sink(c1 = ss1.get());
sink(c2 = ss2.get()); // tainted [NOT DETECTED]
sink(c2 = ss2.get()); // tainted
sink(c3 = ss1.peek());
sink(c4 = ss2.peek()); // tainted [NOT DETECTED]
sink(c4 = ss2.peek()); // tainted
sink(ss1.get(c5));
sink(ss2.get(c6)); // tainted [NOT DETECTED]
sink(ss2.get(c6)); // tainted
sink(c1);
sink(c2); // tainted [NOT DETECTED]
sink(c2); // tainted
sink(c3);
sink(c4); // tainted [NOT DETECTED]
sink(c4); // tainted
sink(c5);
sink(c6); // tainted [NOT DETECTED]
sink(c6); // tainted
}
void test_stringstream_putback()
@@ -193,6 +193,76 @@ void test_stringstream_putback()
sink(ss.get());
sink(ss.putback('b'));
sink(ss.get());
sink(ss.putback(ns_char::source())); // tainted [NOT DETECTED]
sink(ss.get()); // tainted [NOT DETECTED]
sink(ss.putback(ns_char::source())); // tainted
sink(ss.get()); // tainted
}
void test_getline()
{
std::stringstream ss1("abc");
std::stringstream ss2(source());
char b1[1000] = {0};
char b2[1000] = {0};
char b3[1000] = {0};
char b4[1000] = {0};
char b5[1000] = {0};
char b6[1000] = {0};
char b7[1000] = {0};
char b8[1000] = {0};
std::string s1, s2, s3, s4, s5, s6, s7, s8;
sink(ss1.getline(b1, 1000));
sink(ss2.getline(b2, 1000)); // tainted
sink(ss2.getline(b3, 1000)); // tainted
sink(ss1.getline(b3, 1000));
sink(b1);
sink(b2); // tainted
sink(b3); // [FALSE POSITIVE]
sink(ss1.getline(b4, 1000, ' '));
sink(ss2.getline(b5, 1000, ' ')); // tainted
sink(ss2.getline(b6, 1000, ' ')); // tainted
sink(ss1.getline(b6, 1000, ' '));
sink(b4);
sink(b5); // tainted
sink(b6); // [FALSE POSITIVE]
sink(ss2.getline(b7, 1000).getline(b8, 1000)); // tainted
sink(b7); // tainted
sink(b8); // tainted
sink(getline(ss1, s1));
sink(getline(ss2, s2)); // tainted
sink(getline(ss2, s3)); // tainted
sink(getline(ss1, s3));
sink(s1);
sink(s2); // tainted
sink(s3); // [FALSE POSITIVE]
sink(getline(ss1, s4, ' '));
sink(getline(ss2, s5, ' ')); // tainted
sink(getline(ss2, s6, ' ')); // tainted
sink(getline(ss1, s6, ' '));
sink(s4);
sink(s5); // tainted
sink(s6); // [FALSE POSITIVE]
sink(getline(getline(ss2, s7), s8)); // tainted
sink(s7); // tainted
sink(s8); // tainted
}
void test_chaining()
{
std::stringstream ss1(source());
std::stringstream ss2;
char b1[1000] = {0};
char b2[1000] = {0};
sink(ss1.get(b1, 100).unget().get(b2, 100)); // tainted
sink(b1); // tainted
sink(b2); // tainted
sink(ss2.write("abc", 3).flush().write(source(), 3).flush().write("xyz", 3)); // tainted
sink(ss2); // tainted
}

View File

@@ -107,9 +107,9 @@ void array_test(int i) {
arr3[5] = 0;
sink(arr1[5]); // tainted
sink(arr1[i]); // tainted [NOT DETECTED]
sink(arr2[5]); // tainted [NOT DETECTED]
sink(arr2[i]); // tainted [NOT DETECTED]
sink(arr1[i]); // tainted
sink(arr2[5]); // tainted
sink(arr2[i]); // tainted
sink(arr3[5]);
sink(arr3[i]);
}
@@ -127,7 +127,7 @@ void pointer_test() {
*p2 = source();
sink(*p1); // tainted
sink(*p2); // tainted [NOT DETECTED]
sink(*p2); // tainted
sink(*p3);
p3 = &t1;
@@ -258,7 +258,7 @@ void test_lambdas()
c = source();
};
e(t, u, w);
sink(w); // tainted [NOT DETECTED]
sink(w); // tainted
}
// --- taint through return value ---
@@ -348,10 +348,10 @@ void test_outparams()
myNotAssign(e, t);
sink(t); // tainted
sink(a); // tainted [NOT DETECTED by IR]
sink(b); // tainted [NOT DETECTED by IR]
sink(c); // tainted [NOT DETECTED]
sink(d); // tainted [NOT DETECTED]
sink(a); // tainted
sink(b); // tainted
sink(c); // tainted
sink(d); // tainted
sink(e);
}
@@ -468,7 +468,7 @@ void test_swop() {
swop(x, y);
sink(x); // clean [FALSE POSITIVE]
sink(y); // tainted [NOT DETECTED by IR]
sink(y); // tainted
}
// --- getdelim ---

View File

@@ -1,8 +1,11 @@
| arrayassignment.cpp:17:7:17:10 | * ... | arrayassignment.cpp:14:9:14:14 | call to source |
| arrayassignment.cpp:33:7:33:9 | r_x | arrayassignment.cpp:29:8:29:13 | call to source |
| arrayassignment.cpp:57:10:57:12 | call to get | arrayassignment.cpp:54:9:54:14 | call to source |
| arrayassignment.cpp:67:10:67:12 | call to get | arrayassignment.cpp:64:13:64:18 | call to source |
| arrayassignment.cpp:101:7:101:18 | access to array | arrayassignment.cpp:99:17:99:22 | call to source |
| arrayassignment.cpp:135:7:135:10 | ref1 | arrayassignment.cpp:134:9:134:14 | call to source |
| arrayassignment.cpp:140:7:140:11 | * ... | arrayassignment.cpp:139:10:139:15 | call to source |
| arrayassignment.cpp:145:7:145:13 | access to array | arrayassignment.cpp:144:12:144:17 | call to source |
| copyableclass.cpp:40:8:40:9 | s1 | copyableclass.cpp:34:22:34:27 | call to source |
| copyableclass.cpp:41:8:41:9 | s2 | copyableclass.cpp:35:24:35:29 | call to source |
| copyableclass.cpp:42:8:42:9 | s3 | copyableclass.cpp:34:22:34:27 | call to source |
@@ -185,15 +188,69 @@
| stringstream.cpp:66:7:66:10 | ss12 | stringstream.cpp:63:18:63:23 | call to source |
| stringstream.cpp:67:7:67:10 | ss13 | stringstream.cpp:64:36:64:41 | call to source |
| stringstream.cpp:76:11:76:11 | call to operator<< | stringstream.cpp:70:32:70:37 | source |
| stringstream.cpp:78:11:78:11 | call to operator>> | stringstream.cpp:70:32:70:37 | source |
| stringstream.cpp:81:7:81:9 | ss2 | stringstream.cpp:70:32:70:37 | source |
| stringstream.cpp:83:11:83:13 | call to str | stringstream.cpp:70:32:70:37 | source |
| stringstream.cpp:85:7:85:8 | v2 | stringstream.cpp:70:32:70:37 | source |
| stringstream.cpp:100:11:100:11 | call to operator= | stringstream.cpp:100:31:100:36 | call to source |
| stringstream.cpp:103:7:103:9 | ss2 | stringstream.cpp:91:19:91:24 | call to source |
| stringstream.cpp:105:7:105:9 | ss4 | stringstream.cpp:95:44:95:49 | call to source |
| stringstream.cpp:107:7:107:9 | ss6 | stringstream.cpp:100:31:100:36 | call to source |
| stringstream.cpp:120:7:120:9 | ss1 | stringstream.cpp:113:24:113:29 | call to source |
| stringstream.cpp:121:7:121:9 | ss2 | stringstream.cpp:113:24:113:29 | call to source |
| stringstream.cpp:122:7:122:9 | ss3 | stringstream.cpp:115:24:115:29 | call to source |
| stringstream.cpp:123:7:123:9 | ss4 | stringstream.cpp:115:24:115:29 | call to source |
| stringstream.cpp:143:11:143:11 | call to operator<< | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:146:11:146:11 | call to operator>> | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:147:17:147:17 | call to operator>> | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:149:7:149:8 | s2 | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:150:7:150:8 | s3 | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:151:7:151:8 | s4 | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:154:11:154:11 | call to operator>> | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:155:17:155:17 | call to operator>> | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:157:7:157:8 | call to basic_string | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:158:7:158:8 | call to basic_string | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:159:7:159:8 | call to basic_string | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:162:11:162:14 | call to read | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:166:11:166:13 | call to get | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:168:7:168:8 | call to basic_string | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:170:7:170:8 | call to basic_string | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:172:7:172:9 | call to basic_string | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:175:7:175:20 | ... = ... | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:177:7:177:21 | ... = ... | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:179:11:179:13 | call to get | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:181:7:181:8 | c2 | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:183:7:183:8 | c4 | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:185:7:185:8 | c6 | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:196:10:196:16 | call to putback | stringstream.cpp:196:18:196:32 | call to source |
| stringstream.cpp:197:10:197:12 | call to get | stringstream.cpp:196:18:196:32 | call to source |
| stringstream.cpp:215:11:215:17 | call to getline | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:216:11:216:17 | call to getline | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:219:7:219:8 | call to basic_string | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:220:7:220:8 | call to basic_string | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:223:11:223:17 | call to getline | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:224:11:224:17 | call to getline | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:227:7:227:8 | call to basic_string | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:228:7:228:8 | call to basic_string | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:230:29:230:35 | call to getline | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:231:7:231:8 | call to basic_string | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:232:7:232:8 | call to basic_string | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:235:7:235:13 | call to getline | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:236:7:236:13 | call to getline | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:239:7:239:8 | s2 | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:240:7:240:8 | s3 | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:243:7:243:13 | call to getline | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:244:7:244:13 | call to getline | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:247:7:247:8 | s5 | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:248:7:248:8 | s6 | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:250:7:250:13 | call to getline | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:251:7:251:8 | s7 | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:252:7:252:8 | s8 | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:262:32:262:34 | call to get | stringstream.cpp:257:24:257:29 | call to source |
| stringstream.cpp:263:7:263:8 | call to basic_string | stringstream.cpp:257:24:257:29 | call to source |
| stringstream.cpp:264:7:264:8 | call to basic_string | stringstream.cpp:257:24:257:29 | call to source |
| stringstream.cpp:266:62:266:66 | call to write | stringstream.cpp:266:41:266:46 | call to source |
| stringstream.cpp:267:7:267:9 | ss2 | stringstream.cpp:266:41:266:46 | call to source |
| structlikeclass.cpp:35:8:35:9 | s1 | structlikeclass.cpp:29:22:29:27 | call to source |
| structlikeclass.cpp:36:8:36:9 | s2 | structlikeclass.cpp:30:24:30:29 | call to source |
| structlikeclass.cpp:37:8:37:9 | s3 | structlikeclass.cpp:29:22:29:27 | call to source |
@@ -257,7 +314,12 @@
| taint.cpp:91:11:91:11 | d | taint.cpp:77:7:77:12 | call to source |
| taint.cpp:93:11:93:11 | b | taint.cpp:71:22:71:27 | call to source |
| taint.cpp:94:11:94:11 | c | taint.cpp:72:7:72:12 | call to source |
| taint.cpp:109:7:109:13 | access to array | taint.cpp:105:12:105:17 | call to source |
| taint.cpp:110:7:110:13 | access to array | taint.cpp:105:12:105:17 | call to source |
| taint.cpp:111:7:111:13 | access to array | taint.cpp:106:12:106:17 | call to source |
| taint.cpp:112:7:112:13 | access to array | taint.cpp:106:12:106:17 | call to source |
| taint.cpp:129:7:129:9 | * ... | taint.cpp:120:11:120:16 | call to source |
| taint.cpp:130:7:130:9 | * ... | taint.cpp:127:8:127:13 | call to source |
| taint.cpp:134:7:134:9 | * ... | taint.cpp:120:11:120:16 | call to source |
| taint.cpp:137:7:137:9 | * ... | taint.cpp:120:11:120:16 | call to source |
| taint.cpp:151:7:151:12 | call to select | taint.cpp:151:20:151:25 | call to source |
@@ -285,6 +347,8 @@
| taint.cpp:350:7:350:7 | t | taint.cpp:330:6:330:11 | call to source |
| taint.cpp:351:7:351:7 | a | taint.cpp:330:6:330:11 | call to source |
| taint.cpp:352:7:352:7 | b | taint.cpp:330:6:330:11 | call to source |
| taint.cpp:353:7:353:7 | c | taint.cpp:330:6:330:11 | call to source |
| taint.cpp:354:7:354:7 | d | taint.cpp:330:6:330:11 | call to source |
| taint.cpp:372:7:372:7 | a | taint.cpp:365:24:365:29 | source |
| taint.cpp:374:7:374:7 | c | taint.cpp:365:24:365:29 | source |
| taint.cpp:382:7:382:7 | a | taint.cpp:377:23:377:28 | source |
@@ -340,6 +404,7 @@
| vector.cpp:139:7:139:8 | v1 | vector.cpp:126:15:126:20 | call to source |
| vector.cpp:140:7:140:8 | v2 | vector.cpp:127:15:127:20 | call to source |
| vector.cpp:141:7:141:8 | v3 | vector.cpp:128:15:128:20 | call to source |
| vector.cpp:162:8:162:15 | access to array | vector.cpp:161:14:161:19 | call to source |
| vector.cpp:171:13:171:13 | call to operator[] | vector.cpp:170:14:170:19 | call to source |
| vector.cpp:180:13:180:13 | call to operator[] | vector.cpp:179:14:179:19 | call to source |
| vector.cpp:201:13:201:13 | call to operator[] | vector.cpp:200:14:200:19 | call to source |
@@ -364,3 +429,17 @@
| vector.cpp:312:7:312:7 | d | vector.cpp:303:14:303:19 | call to source |
| vector.cpp:324:7:324:8 | v2 | vector.cpp:318:15:318:20 | call to source |
| vector.cpp:326:7:326:8 | v4 | vector.cpp:318:15:318:20 | call to source |
| vector.cpp:342:7:342:8 | v1 | vector.cpp:341:8:341:13 | call to source |
| vector.cpp:347:7:347:8 | v2 | vector.cpp:345:9:345:14 | call to source |
| vector.cpp:357:7:357:8 | v4 | vector.cpp:330:10:330:15 | call to source |
| vector.cpp:361:7:361:8 | v5 | vector.cpp:360:8:360:13 | call to source |
| vector.cpp:363:7:363:8 | v5 | vector.cpp:360:8:360:13 | call to source |
| vector.cpp:367:7:367:8 | v6 | vector.cpp:366:8:366:13 | call to source |
| vector.cpp:369:7:369:8 | v6 | vector.cpp:366:8:366:13 | call to source |
| vector.cpp:374:8:374:9 | v7 | vector.cpp:373:9:373:14 | call to source |
| vector.cpp:379:7:379:8 | v7 | vector.cpp:373:9:373:14 | call to source |
| vector.cpp:383:7:383:8 | v8 | vector.cpp:382:8:382:13 | call to source |
| vector.cpp:385:7:385:8 | v8 | vector.cpp:382:8:382:13 | call to source |
| vector.cpp:392:7:392:8 | v9 | vector.cpp:330:10:330:15 | call to source |
| vector.cpp:392:7:392:8 | v9 | vector.cpp:389:8:389:13 | call to source |
| vector.cpp:400:7:400:9 | v11 | vector.cpp:399:38:399:43 | call to source |

View File

@@ -1,5 +1,4 @@
| arrayassignment.cpp:16:7:16:7 | arrayassignment.cpp:14:9:14:14 | IR only |
| arrayassignment.cpp:17:7:17:10 | arrayassignment.cpp:14:9:14:14 | IR only |
| arrayassignment.cpp:18:7:18:11 | arrayassignment.cpp:14:9:14:14 | IR only |
| arrayassignment.cpp:19:7:19:9 | arrayassignment.cpp:14:9:14:14 | IR only |
| arrayassignment.cpp:31:7:31:7 | arrayassignment.cpp:29:8:29:13 | IR only |
@@ -12,196 +11,117 @@
| arrayassignment.cpp:67:10:67:12 | arrayassignment.cpp:64:13:64:18 | AST only |
| arrayassignment.cpp:67:10:67:15 | arrayassignment.cpp:64:13:64:18 | IR only |
| arrayassignment.cpp:136:7:136:13 | arrayassignment.cpp:134:9:134:14 | IR only |
| arrayassignment.cpp:140:7:140:11 | arrayassignment.cpp:139:10:139:15 | IR only |
| arrayassignment.cpp:141:7:141:13 | arrayassignment.cpp:139:10:139:15 | IR only |
| arrayassignment.cpp:145:7:145:13 | arrayassignment.cpp:144:12:144:17 | IR only |
| arrayassignment.cpp:146:7:146:13 | arrayassignment.cpp:144:12:144:17 | IR only |
| copyableclass.cpp:67:11:67:11 | copyableclass.cpp:67:13:67:18 | AST only |
| copyableclass.cpp:67:11:67:21 | copyableclass.cpp:67:13:67:18 | IR only |
| copyableclass_declonly.cpp:40:8:40:9 | copyableclass_declonly.cpp:34:30:34:35 | AST only |
| copyableclass_declonly.cpp:41:8:41:9 | copyableclass_declonly.cpp:35:32:35:37 | AST only |
| copyableclass_declonly.cpp:42:8:42:9 | copyableclass_declonly.cpp:34:30:34:35 | AST only |
| copyableclass_declonly.cpp:43:8:43:9 | copyableclass_declonly.cpp:38:8:38:13 | AST only |
| copyableclass_declonly.cpp:65:8:65:9 | copyableclass_declonly.cpp:60:56:60:61 | AST only |
| copyableclass_declonly.cpp:66:8:66:9 | copyableclass_declonly.cpp:63:32:63:37 | AST only |
| copyableclass_declonly.cpp:67:11:67:11 | copyableclass_declonly.cpp:67:13:67:18 | AST only |
| format.cpp:57:8:57:13 | format.cpp:56:36:56:49 | AST only |
| format.cpp:62:8:62:13 | format.cpp:61:30:61:43 | AST only |
| format.cpp:67:8:67:13 | format.cpp:66:52:66:65 | AST only |
| format.cpp:72:8:72:13 | format.cpp:71:42:71:55 | AST only |
| format.cpp:83:8:83:13 | format.cpp:82:36:82:41 | AST only |
| format.cpp:88:8:88:13 | format.cpp:87:38:87:43 | AST only |
| format.cpp:94:8:94:13 | format.cpp:93:36:93:49 | AST only |
| format.cpp:100:8:100:13 | format.cpp:99:30:99:43 | AST only |
| format.cpp:105:8:105:13 | format.cpp:104:31:104:45 | AST only |
| format.cpp:110:8:110:14 | format.cpp:109:38:109:52 | AST only |
| format.cpp:115:8:115:13 | format.cpp:114:37:114:50 | AST only |
| movableclass.cpp:65:11:65:11 | movableclass.cpp:65:13:65:18 | AST only |
| movableclass.cpp:65:11:65:21 | movableclass.cpp:65:13:65:18 | IR only |
| smart_pointer.cpp:12:10:12:10 | smart_pointer.cpp:11:52:11:57 | AST only |
| smart_pointer.cpp:13:10:13:10 | smart_pointer.cpp:11:52:11:57 | AST only |
| smart_pointer.cpp:24:10:24:10 | smart_pointer.cpp:23:52:23:57 | AST only |
| smart_pointer.cpp:25:10:25:10 | smart_pointer.cpp:23:52:23:57 | AST only |
| smart_pointer.cpp:52:12:52:14 | smart_pointer.cpp:51:52:51:57 | AST only |
| smart_pointer.cpp:57:12:57:14 | smart_pointer.cpp:56:52:56:57 | AST only |
| standalone_iterators.cpp:40:10:40:10 | standalone_iterators.cpp:39:45:39:51 | AST only |
| standalone_iterators.cpp:41:10:41:10 | standalone_iterators.cpp:39:45:39:51 | AST only |
| standalone_iterators.cpp:42:10:42:10 | standalone_iterators.cpp:39:45:39:51 | AST only |
| standalone_iterators.cpp:46:10:46:10 | standalone_iterators.cpp:45:39:45:45 | AST only |
| standalone_iterators.cpp:47:10:47:10 | standalone_iterators.cpp:45:39:45:45 | AST only |
| standalone_iterators.cpp:48:10:48:10 | standalone_iterators.cpp:45:39:45:45 | AST only |
| string.cpp:30:7:30:7 | string.cpp:26:16:26:21 | AST only |
| string.cpp:32:9:32:13 | string.cpp:26:16:26:21 | AST only |
| string.cpp:38:13:38:17 | string.cpp:14:10:14:15 | AST only |
| string.cpp:42:13:42:17 | string.cpp:14:10:14:15 | AST only |
| string.cpp:45:13:45:17 | string.cpp:14:10:14:15 | AST only |
| string.cpp:55:7:55:8 | string.cpp:50:19:50:26 | IR only |
| string.cpp:56:7:56:8 | string.cpp:50:19:50:24 | AST only |
| string.cpp:69:7:69:8 | string.cpp:61:19:61:24 | AST only |
| string.cpp:70:7:70:8 | string.cpp:61:19:61:24 | AST only |
| string.cpp:92:8:92:9 | string.cpp:87:18:87:23 | AST only |
| string.cpp:93:8:93:9 | string.cpp:88:20:88:25 | AST only |
| string.cpp:94:8:94:9 | string.cpp:90:8:90:13 | AST only |
| string.cpp:113:8:113:9 | string.cpp:109:32:109:37 | AST only |
| string.cpp:114:8:114:9 | string.cpp:111:20:111:25 | AST only |
| string.cpp:121:8:121:8 | string.cpp:119:16:119:21 | AST only |
| string.cpp:125:8:125:8 | string.cpp:119:16:119:21 | AST only |
| string.cpp:129:8:129:8 | string.cpp:119:16:119:21 | AST only |
| string.cpp:134:8:134:8 | string.cpp:132:28:132:33 | AST only |
| string.cpp:144:11:144:11 | string.cpp:141:18:141:23 | AST only |
| string.cpp:145:11:145:11 | string.cpp:141:18:141:23 | AST only |
| string.cpp:146:11:146:11 | string.cpp:141:18:141:23 | AST only |
| string.cpp:149:11:149:11 | string.cpp:149:13:149:18 | AST only |
| string.cpp:158:8:158:9 | string.cpp:154:18:154:23 | AST only |
| string.cpp:125:8:125:11 | string.cpp:119:16:119:21 | IR only |
| string.cpp:161:11:161:11 | string.cpp:154:18:154:23 | AST only |
| string.cpp:162:8:162:9 | string.cpp:154:18:154:23 | AST only |
| string.cpp:165:11:165:11 | string.cpp:165:14:165:19 | AST only |
| string.cpp:166:11:166:11 | string.cpp:165:14:165:19 | AST only |
| string.cpp:167:8:167:9 | string.cpp:165:14:165:19 | AST only |
| string.cpp:171:8:171:9 | string.cpp:154:18:154:23 | AST only |
| string.cpp:176:8:176:9 | string.cpp:174:13:174:18 | AST only |
| string.cpp:184:8:184:10 | string.cpp:181:12:181:26 | AST only |
| string.cpp:198:10:198:15 | string.cpp:190:17:190:22 | AST only |
| string.cpp:199:7:199:8 | string.cpp:190:17:190:22 | AST only |
| string.cpp:201:10:201:15 | string.cpp:191:11:191:25 | AST only |
| string.cpp:202:7:202:8 | string.cpp:191:11:191:25 | AST only |
| string.cpp:205:7:205:8 | string.cpp:193:17:193:22 | AST only |
| string.cpp:219:10:219:15 | string.cpp:210:17:210:22 | AST only |
| string.cpp:220:7:220:8 | string.cpp:210:17:210:22 | AST only |
| string.cpp:223:10:223:15 | string.cpp:210:17:210:22 | AST only |
| string.cpp:224:7:224:8 | string.cpp:210:17:210:22 | AST only |
| string.cpp:227:10:227:15 | string.cpp:211:11:211:25 | AST only |
| string.cpp:228:7:228:8 | string.cpp:211:11:211:25 | AST only |
| string.cpp:242:10:242:16 | string.cpp:233:17:233:22 | AST only |
| string.cpp:243:7:243:8 | string.cpp:233:17:233:22 | AST only |
| string.cpp:246:10:246:16 | string.cpp:233:17:233:22 | AST only |
| string.cpp:247:7:247:8 | string.cpp:233:17:233:22 | AST only |
| string.cpp:250:10:250:16 | string.cpp:234:11:234:25 | AST only |
| string.cpp:251:7:251:8 | string.cpp:234:11:234:25 | AST only |
| string.cpp:264:7:264:8 | string.cpp:258:17:258:22 | AST only |
| string.cpp:274:7:274:8 | string.cpp:269:17:269:22 | AST only |
| string.cpp:276:7:276:8 | string.cpp:271:17:271:22 | AST only |
| string.cpp:281:7:281:8 | string.cpp:269:17:269:22 | AST only |
| string.cpp:282:7:282:8 | string.cpp:269:17:269:22 | AST only |
| string.cpp:283:7:283:8 | string.cpp:271:17:271:22 | AST only |
| string.cpp:284:7:284:8 | string.cpp:271:17:271:22 | AST only |
| string.cpp:292:7:292:8 | string.cpp:288:17:288:22 | AST only |
| string.cpp:293:7:293:8 | string.cpp:289:17:289:22 | AST only |
| string.cpp:294:7:294:8 | string.cpp:290:17:290:22 | AST only |
| string.cpp:300:7:300:8 | string.cpp:288:17:288:22 | AST only |
| string.cpp:302:7:302:8 | string.cpp:290:17:290:22 | AST only |
| string.cpp:311:9:311:12 | string.cpp:308:16:308:21 | AST only |
| string.cpp:322:9:322:14 | string.cpp:319:16:319:21 | AST only |
| string.cpp:339:7:339:7 | string.cpp:335:9:335:23 | AST only |
| string.cpp:340:7:340:7 | string.cpp:336:12:336:26 | AST only |
| string.cpp:341:7:341:7 | string.cpp:335:9:335:23 | AST only |
| string.cpp:349:7:349:9 | string.cpp:348:18:348:32 | AST only |
| string.cpp:350:11:350:14 | string.cpp:348:18:348:32 | AST only |
| string.cpp:361:11:361:16 | string.cpp:356:18:356:23 | AST only |
| string.cpp:362:8:362:9 | string.cpp:356:18:356:23 | AST only |
| string.cpp:380:8:380:8 | string.cpp:372:18:372:23 | AST only |
| string.cpp:381:13:381:13 | string.cpp:372:18:372:23 | AST only |
| string.cpp:380:8:380:14 | string.cpp:372:18:372:23 | IR only |
| string.cpp:381:13:381:15 | string.cpp:372:18:372:23 | IR only |
| string.cpp:394:8:394:8 | string.cpp:387:18:387:23 | AST only |
| string.cpp:395:8:395:8 | string.cpp:387:18:387:23 | AST only |
| string.cpp:397:8:397:8 | string.cpp:387:18:387:23 | AST only |
| string.cpp:399:8:399:8 | string.cpp:387:18:387:23 | AST only |
| string.cpp:402:8:402:8 | string.cpp:387:18:387:23 | AST only |
| string.cpp:405:8:405:8 | string.cpp:387:18:387:23 | AST only |
| string.cpp:402:8:402:11 | string.cpp:387:18:387:23 | IR only |
| string.cpp:405:8:405:11 | string.cpp:387:18:387:23 | IR only |
| string.cpp:407:8:407:8 | string.cpp:387:18:387:23 | AST only |
| string.cpp:409:8:409:8 | string.cpp:387:18:387:23 | AST only |
| string.cpp:413:8:413:8 | string.cpp:387:18:387:23 | AST only |
| string.cpp:413:8:413:11 | string.cpp:387:18:387:23 | IR only |
| string.cpp:427:10:427:15 | string.cpp:422:14:422:19 | AST only |
| string.cpp:428:7:428:8 | string.cpp:422:14:422:19 | AST only |
| string.cpp:442:10:442:15 | string.cpp:442:32:442:46 | AST only |
| string.cpp:443:8:443:8 | string.cpp:442:32:442:46 | AST only |
| string.cpp:455:10:455:15 | string.cpp:450:18:450:23 | AST only |
| string.cpp:456:8:456:8 | string.cpp:450:18:450:23 | AST only |
| string.cpp:458:11:458:16 | string.cpp:450:18:450:23 | AST only |
| string.cpp:459:8:459:9 | string.cpp:450:18:450:23 | AST only |
| string.cpp:471:10:471:15 | string.cpp:466:18:466:23 | AST only |
| string.cpp:472:8:472:8 | string.cpp:466:18:466:23 | AST only |
| string.cpp:474:11:474:16 | string.cpp:466:18:466:23 | AST only |
| string.cpp:475:8:475:9 | string.cpp:466:18:466:23 | AST only |
| string.cpp:487:10:487:15 | string.cpp:482:18:482:23 | AST only |
| string.cpp:488:8:488:8 | string.cpp:482:18:482:23 | AST only |
| string.cpp:491:8:491:9 | string.cpp:482:18:482:23 | AST only |
| string.cpp:504:7:504:8 | string.cpp:497:14:497:19 | AST only |
| string.cpp:506:7:506:8 | string.cpp:497:14:497:19 | AST only |
| string.cpp:515:9:515:13 | string.cpp:514:14:514:28 | AST only |
| string.cpp:516:9:516:12 | string.cpp:514:14:514:28 | AST only |
| string.cpp:529:11:529:11 | string.cpp:529:20:529:25 | AST only |
| string.cpp:530:21:530:21 | string.cpp:530:24:530:29 | AST only |
| string.cpp:531:25:531:25 | string.cpp:531:15:531:20 | AST only |
| string.cpp:534:8:534:8 | string.cpp:529:20:529:25 | AST only |
| string.cpp:535:8:535:8 | string.cpp:529:20:529:25 | AST only |
| string.cpp:536:8:536:8 | string.cpp:530:24:530:29 | AST only |
| string.cpp:537:8:537:8 | string.cpp:531:15:531:20 | AST only |
| string.cpp:549:11:549:16 | string.cpp:549:27:549:32 | AST only |
| string.cpp:550:24:550:29 | string.cpp:550:31:550:36 | AST only |
| string.cpp:554:8:554:8 | string.cpp:549:27:549:32 | AST only |
| string.cpp:555:8:555:8 | string.cpp:549:27:549:32 | AST only |
| string.cpp:556:8:556:8 | string.cpp:550:31:550:36 | AST only |
| string.cpp:557:8:557:8 | string.cpp:551:18:551:23 | AST only |
| stringstream.cpp:32:11:32:11 | stringstream.cpp:32:14:32:21 | IR only |
| stringstream.cpp:32:11:32:22 | stringstream.cpp:32:14:32:19 | IR only |
| stringstream.cpp:32:11:32:22 | stringstream.cpp:32:14:32:21 | IR only |
| stringstream.cpp:33:20:33:20 | stringstream.cpp:33:23:33:30 | IR only |
| stringstream.cpp:33:20:33:31 | stringstream.cpp:33:23:33:28 | IR only |
| stringstream.cpp:33:20:33:31 | stringstream.cpp:33:23:33:30 | IR only |
| stringstream.cpp:34:23:34:23 | stringstream.cpp:34:14:34:21 | IR only |
| stringstream.cpp:34:23:34:31 | stringstream.cpp:34:14:34:19 | IR only |
| stringstream.cpp:34:23:34:31 | stringstream.cpp:34:14:34:21 | IR only |
| stringstream.cpp:35:11:35:11 | stringstream.cpp:29:16:29:21 | AST only |
| stringstream.cpp:38:7:38:9 | stringstream.cpp:32:14:32:19 | AST only |
| stringstream.cpp:39:7:39:9 | stringstream.cpp:33:23:33:28 | AST only |
| stringstream.cpp:40:7:40:9 | stringstream.cpp:34:14:34:19 | AST only |
| stringstream.cpp:41:7:41:9 | stringstream.cpp:29:16:29:21 | AST only |
| stringstream.cpp:43:11:43:13 | stringstream.cpp:32:14:32:19 | AST only |
| stringstream.cpp:44:11:44:13 | stringstream.cpp:33:23:33:28 | AST only |
| stringstream.cpp:45:11:45:13 | stringstream.cpp:34:14:34:19 | AST only |
| stringstream.cpp:46:11:46:13 | stringstream.cpp:29:16:29:21 | AST only |
| stringstream.cpp:52:7:52:9 | stringstream.cpp:49:10:49:15 | AST only |
| stringstream.cpp:53:7:53:9 | stringstream.cpp:50:10:50:15 | AST only |
| stringstream.cpp:56:11:56:13 | stringstream.cpp:56:15:56:29 | AST only |
| stringstream.cpp:57:44:57:46 | stringstream.cpp:57:25:57:39 | AST only |
| stringstream.cpp:59:7:59:9 | stringstream.cpp:56:15:56:29 | AST only |
| stringstream.cpp:60:7:60:10 | stringstream.cpp:57:25:57:39 | AST only |
| stringstream.cpp:63:12:63:16 | stringstream.cpp:63:18:63:23 | AST only |
| stringstream.cpp:64:54:64:58 | stringstream.cpp:64:36:64:41 | AST only |
| stringstream.cpp:66:7:66:10 | stringstream.cpp:63:18:63:23 | AST only |
| stringstream.cpp:67:7:67:10 | stringstream.cpp:64:36:64:41 | AST only |
| stringstream.cpp:76:11:76:11 | stringstream.cpp:70:32:70:37 | AST only |
| stringstream.cpp:81:7:81:9 | stringstream.cpp:70:32:70:37 | AST only |
| stringstream.cpp:83:11:83:13 | stringstream.cpp:70:32:70:37 | AST only |
| stringstream.cpp:78:11:78:11 | stringstream.cpp:70:32:70:37 | AST only |
| stringstream.cpp:100:11:100:11 | stringstream.cpp:100:31:100:36 | AST only |
| stringstream.cpp:103:7:103:9 | stringstream.cpp:91:19:91:24 | AST only |
| stringstream.cpp:105:7:105:9 | stringstream.cpp:95:44:95:49 | AST only |
| stringstream.cpp:107:7:107:9 | stringstream.cpp:100:31:100:36 | AST only |
| stringstream.cpp:121:7:121:9 | stringstream.cpp:113:24:113:29 | AST only |
| stringstream.cpp:123:7:123:9 | stringstream.cpp:115:24:115:29 | AST only |
| stringstream.cpp:143:11:143:11 | stringstream.cpp:143:14:143:21 | IR only |
| stringstream.cpp:143:11:143:22 | stringstream.cpp:143:14:143:19 | IR only |
| stringstream.cpp:143:11:143:22 | stringstream.cpp:143:14:143:21 | IR only |
| stringstream.cpp:146:11:146:11 | stringstream.cpp:143:14:143:19 | AST only |
| stringstream.cpp:147:17:147:17 | stringstream.cpp:143:14:143:19 | AST only |
| stringstream.cpp:151:7:151:8 | stringstream.cpp:143:14:143:19 | AST only |
| stringstream.cpp:154:11:154:11 | stringstream.cpp:143:14:143:19 | AST only |
| stringstream.cpp:155:17:155:17 | stringstream.cpp:143:14:143:19 | AST only |
| stringstream.cpp:159:7:159:8 | stringstream.cpp:143:14:143:19 | AST only |
| stringstream.cpp:162:11:162:14 | stringstream.cpp:143:14:143:19 | AST only |
| stringstream.cpp:166:11:166:13 | stringstream.cpp:143:14:143:19 | AST only |
| stringstream.cpp:179:11:179:13 | stringstream.cpp:143:14:143:19 | AST only |
| stringstream.cpp:196:10:196:16 | stringstream.cpp:196:18:196:32 | AST only |
| stringstream.cpp:215:11:215:17 | stringstream.cpp:203:24:203:29 | AST only |
| stringstream.cpp:216:11:216:17 | stringstream.cpp:203:24:203:29 | AST only |
| stringstream.cpp:223:11:223:17 | stringstream.cpp:203:24:203:29 | AST only |
| stringstream.cpp:224:11:224:17 | stringstream.cpp:203:24:203:29 | AST only |
| stringstream.cpp:230:29:230:35 | stringstream.cpp:203:24:203:29 | AST only |
| stringstream.cpp:232:7:232:8 | stringstream.cpp:203:24:203:29 | AST only |
| stringstream.cpp:235:7:235:13 | stringstream.cpp:203:24:203:29 | AST only |
| stringstream.cpp:236:7:236:13 | stringstream.cpp:203:24:203:29 | AST only |
| stringstream.cpp:243:7:243:13 | stringstream.cpp:203:24:203:29 | AST only |
| stringstream.cpp:244:7:244:13 | stringstream.cpp:203:24:203:29 | AST only |
| stringstream.cpp:250:7:250:13 | stringstream.cpp:203:24:203:29 | AST only |
| stringstream.cpp:252:7:252:8 | stringstream.cpp:203:24:203:29 | AST only |
| stringstream.cpp:262:32:262:34 | stringstream.cpp:257:24:257:29 | AST only |
| stringstream.cpp:264:7:264:8 | stringstream.cpp:257:24:257:29 | AST only |
| stringstream.cpp:266:62:266:66 | stringstream.cpp:266:41:266:46 | AST only |
| stringstream.cpp:267:7:267:9 | stringstream.cpp:266:41:266:46 | AST only |
| swap1.cpp:78:12:78:16 | swap1.cpp:69:23:69:23 | AST only |
| swap1.cpp:87:13:87:17 | swap1.cpp:82:16:82:21 | AST only |
| swap1.cpp:88:13:88:17 | swap1.cpp:81:27:81:28 | AST only |
@@ -218,34 +138,17 @@
| taint.cpp:41:7:41:13 | taint.cpp:35:12:35:17 | AST only |
| taint.cpp:42:7:42:13 | taint.cpp:35:12:35:17 | AST only |
| taint.cpp:43:7:43:13 | taint.cpp:37:22:37:27 | AST only |
| taint.cpp:109:7:109:13 | taint.cpp:105:12:105:17 | IR only |
| taint.cpp:110:7:110:13 | taint.cpp:105:12:105:17 | IR only |
| taint.cpp:111:7:111:13 | taint.cpp:106:12:106:17 | IR only |
| taint.cpp:112:7:112:13 | taint.cpp:106:12:106:17 | IR only |
| taint.cpp:130:7:130:9 | taint.cpp:127:8:127:13 | IR only |
| taint.cpp:137:7:137:9 | taint.cpp:120:11:120:16 | AST only |
| taint.cpp:173:8:173:13 | taint.cpp:164:19:164:24 | AST only |
| taint.cpp:195:7:195:7 | taint.cpp:192:23:192:28 | AST only |
| taint.cpp:195:7:195:7 | taint.cpp:193:6:193:6 | AST only |
| taint.cpp:236:3:236:6 | taint.cpp:223:10:223:15 | AST only |
| taint.cpp:261:7:261:7 | taint.cpp:258:7:258:12 | AST only |
| taint.cpp:351:7:351:7 | taint.cpp:330:6:330:11 | AST only |
| taint.cpp:352:7:352:7 | taint.cpp:330:6:330:11 | AST only |
| taint.cpp:372:7:372:7 | taint.cpp:365:24:365:29 | AST only |
| taint.cpp:374:7:374:7 | taint.cpp:365:24:365:29 | AST only |
| taint.cpp:391:7:391:7 | taint.cpp:385:27:385:32 | AST only |
| taint.cpp:423:7:423:7 | taint.cpp:422:14:422:19 | AST only |
| taint.cpp:424:9:424:17 | taint.cpp:422:14:422:19 | AST only |
| taint.cpp:429:7:429:7 | taint.cpp:428:13:428:18 | IR only |
| taint.cpp:438:7:438:7 | taint.cpp:437:15:437:20 | AST only |
| taint.cpp:439:10:439:18 | taint.cpp:437:15:437:20 | AST only |
| taint.cpp:446:7:446:7 | taint.cpp:445:14:445:28 | AST only |
| taint.cpp:431:9:431:17 | taint.cpp:428:13:428:18 | IR only |
| taint.cpp:447:9:447:17 | taint.cpp:445:14:445:28 | AST only |
| taint.cpp:471:7:471:7 | taint.cpp:462:6:462:11 | AST only |
| vector.cpp:20:8:20:8 | vector.cpp:16:43:16:49 | AST only |
| vector.cpp:24:8:24:8 | vector.cpp:16:43:16:49 | AST only |
| vector.cpp:28:8:28:8 | vector.cpp:16:43:16:49 | AST only |
| vector.cpp:33:8:33:8 | vector.cpp:16:43:16:49 | AST only |
| vector.cpp:24:8:24:11 | vector.cpp:16:43:16:49 | IR only |
| vector.cpp:52:7:52:8 | vector.cpp:51:10:51:15 | AST only |
| vector.cpp:53:9:53:9 | vector.cpp:51:10:51:15 | AST only |
| vector.cpp:54:9:54:9 | vector.cpp:51:10:51:15 | AST only |
@@ -258,52 +161,38 @@
| vector.cpp:65:9:65:9 | vector.cpp:63:10:63:15 | AST only |
| vector.cpp:66:9:66:9 | vector.cpp:63:10:63:15 | AST only |
| vector.cpp:67:9:67:9 | vector.cpp:63:10:63:15 | AST only |
| vector.cpp:70:7:70:8 | vector.cpp:69:15:69:20 | AST only |
| vector.cpp:71:10:71:14 | vector.cpp:69:15:69:20 | AST only |
| vector.cpp:72:10:72:13 | vector.cpp:69:15:69:20 | AST only |
| vector.cpp:75:7:75:8 | vector.cpp:74:17:74:22 | AST only |
| vector.cpp:76:7:76:18 | vector.cpp:74:17:74:22 | AST only |
| vector.cpp:83:7:83:8 | vector.cpp:81:17:81:22 | AST only |
| vector.cpp:84:10:84:14 | vector.cpp:81:17:81:22 | AST only |
| vector.cpp:85:10:85:13 | vector.cpp:81:17:81:22 | AST only |
| vector.cpp:97:7:97:8 | vector.cpp:96:13:96:18 | AST only |
| vector.cpp:98:10:98:11 | vector.cpp:96:13:96:18 | AST only |
| vector.cpp:99:10:99:11 | vector.cpp:96:13:96:18 | AST only |
| vector.cpp:100:10:100:11 | vector.cpp:96:13:96:18 | AST only |
| vector.cpp:109:7:109:8 | vector.cpp:106:15:106:20 | AST only |
| vector.cpp:112:7:112:8 | vector.cpp:107:15:107:20 | AST only |
| vector.cpp:117:7:117:8 | vector.cpp:106:15:106:20 | AST only |
| vector.cpp:118:7:118:8 | vector.cpp:106:15:106:20 | AST only |
| vector.cpp:119:7:119:8 | vector.cpp:107:15:107:20 | AST only |
| vector.cpp:120:7:120:8 | vector.cpp:107:15:107:20 | AST only |
| vector.cpp:130:7:130:8 | vector.cpp:126:15:126:20 | AST only |
| vector.cpp:131:7:131:8 | vector.cpp:127:15:127:20 | AST only |
| vector.cpp:132:7:132:8 | vector.cpp:128:15:128:20 | AST only |
| vector.cpp:139:7:139:8 | vector.cpp:126:15:126:20 | AST only |
| vector.cpp:140:7:140:8 | vector.cpp:127:15:127:20 | AST only |
| vector.cpp:141:7:141:8 | vector.cpp:128:15:128:20 | AST only |
| vector.cpp:162:8:162:15 | vector.cpp:161:14:161:19 | IR only |
| vector.cpp:171:13:171:13 | vector.cpp:170:14:170:19 | AST only |
| vector.cpp:180:13:180:13 | vector.cpp:179:14:179:19 | AST only |
| vector.cpp:201:13:201:13 | vector.cpp:200:14:200:19 | AST only |
| vector.cpp:242:7:242:8 | vector.cpp:238:17:238:30 | AST only |
| vector.cpp:243:7:243:8 | vector.cpp:239:15:239:20 | AST only |
| vector.cpp:258:8:258:9 | vector.cpp:239:15:239:20 | AST only |
| vector.cpp:259:8:259:9 | vector.cpp:239:15:239:20 | AST only |
| vector.cpp:260:8:260:9 | vector.cpp:239:15:239:20 | AST only |
| vector.cpp:261:8:261:9 | vector.cpp:239:15:239:20 | AST only |
| vector.cpp:273:8:273:9 | vector.cpp:269:18:269:31 | AST only |
| vector.cpp:274:8:274:9 | vector.cpp:270:18:270:35 | AST only |
| vector.cpp:275:8:275:9 | vector.cpp:271:18:271:34 | AST only |
| vector.cpp:285:7:285:8 | vector.cpp:284:15:284:20 | AST only |
| vector.cpp:286:10:286:13 | vector.cpp:284:15:284:20 | AST only |
| vector.cpp:287:7:287:18 | vector.cpp:284:15:284:20 | AST only |
| vector.cpp:290:7:290:8 | vector.cpp:289:17:289:30 | AST only |
| vector.cpp:291:10:291:13 | vector.cpp:289:17:289:30 | AST only |
| vector.cpp:292:7:292:18 | vector.cpp:289:17:289:30 | AST only |
| vector.cpp:308:9:308:14 | vector.cpp:303:14:303:19 | AST only |
| vector.cpp:309:7:309:7 | vector.cpp:303:14:303:19 | AST only |
| vector.cpp:311:9:311:14 | vector.cpp:303:14:303:19 | AST only |
| vector.cpp:312:7:312:7 | vector.cpp:303:14:303:19 | AST only |
| vector.cpp:324:7:324:8 | vector.cpp:318:15:318:20 | AST only |
| vector.cpp:326:7:326:8 | vector.cpp:318:15:318:20 | AST only |
| vector.cpp:342:7:342:8 | vector.cpp:341:8:341:13 | AST only |
| vector.cpp:347:7:347:8 | vector.cpp:345:9:345:14 | AST only |
| vector.cpp:357:7:357:8 | vector.cpp:330:10:330:15 | AST only |
| vector.cpp:361:7:361:8 | vector.cpp:360:8:360:13 | AST only |
| vector.cpp:363:7:363:8 | vector.cpp:360:8:360:13 | AST only |
| vector.cpp:367:7:367:8 | vector.cpp:366:8:366:13 | AST only |
| vector.cpp:369:7:369:8 | vector.cpp:366:8:366:13 | AST only |
| vector.cpp:374:8:374:9 | vector.cpp:373:9:373:14 | AST only |
| vector.cpp:379:7:379:8 | vector.cpp:373:9:373:14 | AST only |
| vector.cpp:383:7:383:8 | vector.cpp:382:8:382:13 | AST only |
| vector.cpp:385:7:385:8 | vector.cpp:382:8:382:13 | AST only |
| vector.cpp:392:7:392:8 | vector.cpp:330:10:330:15 | AST only |
| vector.cpp:392:7:392:8 | vector.cpp:389:8:389:13 | AST only |
| vector.cpp:400:7:400:9 | vector.cpp:399:38:399:43 | AST only |

View File

@@ -24,7 +24,22 @@
| copyableclass.cpp:65:8:65:9 | s1 | copyableclass.cpp:60:40:60:45 | call to source |
| copyableclass.cpp:66:8:66:9 | s2 | copyableclass.cpp:63:24:63:29 | call to source |
| copyableclass.cpp:67:11:67:21 | (reference dereference) | copyableclass.cpp:67:13:67:18 | call to source |
| format.cpp:157:7:157:22 | (int)... | format.cpp:147:12:147:25 | call to source |
| copyableclass_declonly.cpp:40:8:40:9 | s1 | copyableclass_declonly.cpp:34:30:34:35 | call to source |
| copyableclass_declonly.cpp:41:8:41:9 | s2 | copyableclass_declonly.cpp:35:32:35:37 | call to source |
| copyableclass_declonly.cpp:43:8:43:9 | s4 | copyableclass_declonly.cpp:38:8:38:13 | call to source |
| copyableclass_declonly.cpp:65:8:65:9 | s1 | copyableclass_declonly.cpp:60:56:60:61 | call to source |
| copyableclass_declonly.cpp:66:8:66:9 | s2 | copyableclass_declonly.cpp:63:32:63:37 | call to source |
| format.cpp:57:8:57:13 | Argument 0 indirection | format.cpp:56:36:56:49 | call to source |
| format.cpp:62:8:62:13 | Argument 0 indirection | format.cpp:61:30:61:43 | call to source |
| format.cpp:67:8:67:13 | Argument 0 indirection | format.cpp:66:52:66:65 | call to source |
| format.cpp:72:8:72:13 | Argument 0 indirection | format.cpp:71:42:71:55 | call to source |
| format.cpp:83:8:83:13 | Argument 0 indirection | format.cpp:82:36:82:41 | call to source |
| format.cpp:88:8:88:13 | Argument 0 indirection | format.cpp:87:38:87:43 | call to source |
| format.cpp:94:8:94:13 | Argument 0 indirection | format.cpp:93:36:93:49 | call to source |
| format.cpp:100:8:100:13 | Argument 0 indirection | format.cpp:99:30:99:43 | call to source |
| format.cpp:105:8:105:13 | Argument 0 indirection | format.cpp:104:31:104:45 | call to source |
| format.cpp:110:8:110:14 | Argument 0 indirection | format.cpp:109:38:109:52 | call to source |
| format.cpp:115:8:115:13 | Argument 0 indirection | format.cpp:114:37:114:50 | call to source |
| format.cpp:157:7:157:22 | access to array | format.cpp:147:12:147:25 | call to source |
| format.cpp:158:7:158:27 | ... + ... | format.cpp:148:16:148:30 | call to source |
| movableclass.cpp:44:8:44:9 | s1 | movableclass.cpp:39:21:39:26 | call to source |
@@ -34,42 +49,136 @@
| movableclass.cpp:55:8:55:9 | s2 | movableclass.cpp:52:23:52:28 | call to source |
| movableclass.cpp:64:8:64:9 | s2 | movableclass.cpp:23:55:23:60 | call to source |
| movableclass.cpp:65:11:65:21 | (reference dereference) | movableclass.cpp:65:13:65:18 | call to source |
| string.cpp:28:7:28:7 | (const char *)... | string.cpp:24:12:24:17 | call to source |
| smart_pointer.cpp:13:10:13:10 | Argument 0 indirection | smart_pointer.cpp:11:52:11:57 | call to source |
| smart_pointer.cpp:25:10:25:10 | Argument 0 indirection | smart_pointer.cpp:23:52:23:57 | call to source |
| smart_pointer.cpp:52:12:52:14 | call to get | smart_pointer.cpp:51:52:51:57 | call to source |
| smart_pointer.cpp:57:12:57:14 | call to get | smart_pointer.cpp:56:52:56:57 | call to source |
| standalone_iterators.cpp:40:10:40:10 | call to operator* | standalone_iterators.cpp:39:45:39:51 | source1 |
| standalone_iterators.cpp:46:10:46:10 | call to operator* | standalone_iterators.cpp:45:39:45:45 | source1 |
| string.cpp:28:7:28:7 | a | string.cpp:24:12:24:17 | call to source |
| string.cpp:30:7:30:7 | Argument 0 indirection | string.cpp:26:16:26:21 | call to source |
| string.cpp:55:7:55:8 | cs | string.cpp:50:19:50:24 | call to source |
| string.cpp:55:7:55:8 | cs | string.cpp:50:19:50:26 | (const char *)... |
| string.cpp:56:7:56:8 | Argument 0 indirection | string.cpp:50:19:50:24 | call to source |
| string.cpp:70:7:70:8 | Argument 0 indirection | string.cpp:61:19:61:24 | call to source |
| string.cpp:92:8:92:9 | Argument 0 indirection | string.cpp:87:18:87:23 | call to source |
| string.cpp:93:8:93:9 | Argument 0 indirection | string.cpp:88:20:88:25 | call to source |
| string.cpp:94:8:94:9 | Argument 0 indirection | string.cpp:90:8:90:13 | call to source |
| string.cpp:113:8:113:9 | Argument 0 indirection | string.cpp:109:32:109:37 | call to source |
| string.cpp:114:8:114:9 | Argument 0 indirection | string.cpp:111:20:111:25 | call to source |
| string.cpp:121:8:121:8 | c | string.cpp:119:16:119:21 | call to source |
| string.cpp:125:8:125:8 | call to operator* | string.cpp:119:16:119:21 | call to source |
| string.cpp:125:8:125:11 | (reference dereference) | string.cpp:119:16:119:21 | call to source |
| string.cpp:129:8:129:8 | (reference dereference) | string.cpp:119:16:119:21 | call to source |
| string.cpp:129:8:129:8 | c | string.cpp:119:16:119:21 | call to source |
| string.cpp:134:8:134:8 | (reference dereference) | string.cpp:132:28:132:33 | call to source |
| string.cpp:134:8:134:8 | c | string.cpp:132:28:132:33 | call to source |
| string.cpp:144:11:144:11 | call to operator+ | string.cpp:141:18:141:23 | call to source |
| string.cpp:145:11:145:11 | call to operator+ | string.cpp:141:18:141:23 | call to source |
| string.cpp:146:11:146:11 | call to operator+ | string.cpp:141:18:141:23 | call to source |
| string.cpp:149:11:149:11 | call to operator+ | string.cpp:149:13:149:18 | call to source |
| string.cpp:158:8:158:9 | Argument 0 indirection | string.cpp:154:18:154:23 | call to source |
| string.cpp:162:8:162:9 | Argument 0 indirection | string.cpp:154:18:154:23 | call to source |
| string.cpp:167:8:167:9 | Argument 0 indirection | string.cpp:165:14:165:19 | call to source |
| string.cpp:171:8:171:9 | Argument 0 indirection | string.cpp:154:18:154:23 | call to source |
| string.cpp:176:8:176:9 | Argument 0 indirection | string.cpp:174:13:174:18 | call to source |
| string.cpp:184:8:184:10 | Argument 0 indirection | string.cpp:181:12:181:26 | call to source |
| string.cpp:199:7:199:8 | Argument 0 indirection | string.cpp:190:17:190:22 | call to source |
| string.cpp:202:7:202:8 | Argument 0 indirection | string.cpp:191:11:191:25 | call to source |
| string.cpp:205:7:205:8 | Argument 0 indirection | string.cpp:193:17:193:22 | call to source |
| string.cpp:220:7:220:8 | Argument 0 indirection | string.cpp:210:17:210:22 | call to source |
| string.cpp:224:7:224:8 | Argument 0 indirection | string.cpp:210:17:210:22 | call to source |
| string.cpp:228:7:228:8 | Argument 0 indirection | string.cpp:211:11:211:25 | call to source |
| string.cpp:243:7:243:8 | Argument 0 indirection | string.cpp:233:17:233:22 | call to source |
| string.cpp:247:7:247:8 | Argument 0 indirection | string.cpp:233:17:233:22 | call to source |
| string.cpp:251:7:251:8 | Argument 0 indirection | string.cpp:234:11:234:25 | call to source |
| string.cpp:264:7:264:8 | Argument 0 indirection | string.cpp:258:17:258:22 | call to source |
| string.cpp:274:7:274:8 | Argument 0 indirection | string.cpp:269:17:269:22 | call to source |
| string.cpp:276:7:276:8 | Argument 0 indirection | string.cpp:271:17:271:22 | call to source |
| string.cpp:281:7:281:8 | Argument 0 indirection | string.cpp:269:17:269:22 | call to source |
| string.cpp:282:7:282:8 | Argument 0 indirection | string.cpp:269:17:269:22 | call to source |
| string.cpp:283:7:283:8 | Argument 0 indirection | string.cpp:271:17:271:22 | call to source |
| string.cpp:284:7:284:8 | Argument 0 indirection | string.cpp:271:17:271:22 | call to source |
| string.cpp:292:7:292:8 | Argument 0 indirection | string.cpp:288:17:288:22 | call to source |
| string.cpp:293:7:293:8 | Argument 0 indirection | string.cpp:289:17:289:22 | call to source |
| string.cpp:294:7:294:8 | Argument 0 indirection | string.cpp:290:17:290:22 | call to source |
| string.cpp:300:7:300:8 | Argument 0 indirection | string.cpp:288:17:288:22 | call to source |
| string.cpp:302:7:302:8 | Argument 0 indirection | string.cpp:290:17:290:22 | call to source |
| string.cpp:322:9:322:14 | call to substr | string.cpp:319:16:319:21 | call to source |
| string.cpp:362:8:362:9 | Argument 0 indirection | string.cpp:356:18:356:23 | call to source |
| string.cpp:380:8:380:8 | call to operator* | string.cpp:372:18:372:23 | call to source |
| string.cpp:380:8:380:14 | (reference dereference) | string.cpp:372:18:372:23 | call to source |
| string.cpp:381:13:381:13 | call to operator[] | string.cpp:372:18:372:23 | call to source |
| string.cpp:381:13:381:15 | (reference dereference) | string.cpp:372:18:372:23 | call to source |
| string.cpp:402:8:402:8 | call to operator* | string.cpp:387:18:387:23 | call to source |
| string.cpp:402:8:402:11 | (reference dereference) | string.cpp:387:18:387:23 | call to source |
| string.cpp:405:8:405:8 | call to operator* | string.cpp:387:18:387:23 | call to source |
| string.cpp:405:8:405:11 | (reference dereference) | string.cpp:387:18:387:23 | call to source |
| string.cpp:413:8:413:8 | call to operator* | string.cpp:387:18:387:23 | call to source |
| string.cpp:413:8:413:11 | (reference dereference) | string.cpp:387:18:387:23 | call to source |
| string.cpp:428:7:428:8 | Argument 0 indirection | string.cpp:422:14:422:19 | call to source |
| string.cpp:443:8:443:8 | Argument 0 indirection | string.cpp:442:32:442:46 | call to source |
| string.cpp:456:8:456:8 | Argument 0 indirection | string.cpp:450:18:450:23 | call to source |
| string.cpp:459:8:459:9 | Argument 0 indirection | string.cpp:450:18:450:23 | call to source |
| string.cpp:472:8:472:8 | Argument 0 indirection | string.cpp:466:18:466:23 | call to source |
| string.cpp:475:8:475:9 | Argument 0 indirection | string.cpp:466:18:466:23 | call to source |
| string.cpp:488:8:488:8 | Argument 0 indirection | string.cpp:482:18:482:23 | call to source |
| string.cpp:491:8:491:9 | Argument 0 indirection | string.cpp:482:18:482:23 | call to source |
| string.cpp:504:7:504:8 | Argument 0 indirection | string.cpp:497:14:497:19 | call to source |
| string.cpp:506:7:506:8 | Argument 0 indirection | string.cpp:497:14:497:19 | call to source |
| string.cpp:535:8:535:8 | Argument 0 indirection | string.cpp:529:20:529:25 | call to source |
| string.cpp:537:8:537:8 | Argument 0 indirection | string.cpp:531:15:531:20 | call to source |
| string.cpp:555:8:555:8 | Argument 0 indirection | string.cpp:549:27:549:32 | call to source |
| string.cpp:557:8:557:8 | Argument 0 indirection | string.cpp:551:18:551:23 | call to source |
| stringstream.cpp:32:11:32:11 | call to operator<< | stringstream.cpp:32:14:32:19 | call to source |
| stringstream.cpp:32:11:32:11 | call to operator<< | stringstream.cpp:32:14:32:21 | (const char *)... |
| stringstream.cpp:32:11:32:22 | (const basic_ostream<char, char_traits<char>>)... | stringstream.cpp:32:14:32:19 | call to source |
| stringstream.cpp:32:11:32:22 | (const basic_ostream<char, char_traits<char>>)... | stringstream.cpp:32:14:32:21 | (const char *)... |
| stringstream.cpp:32:11:32:22 | (reference dereference) | stringstream.cpp:32:14:32:19 | call to source |
| stringstream.cpp:32:11:32:22 | (reference dereference) | stringstream.cpp:32:14:32:21 | (const char *)... |
| stringstream.cpp:32:11:32:22 | (reference to) | stringstream.cpp:32:14:32:19 | call to source |
| stringstream.cpp:32:11:32:22 | (reference to) | stringstream.cpp:32:14:32:21 | (const char *)... |
| stringstream.cpp:33:20:33:20 | call to operator<< | stringstream.cpp:33:23:33:28 | call to source |
| stringstream.cpp:33:20:33:20 | call to operator<< | stringstream.cpp:33:23:33:30 | (const char *)... |
| stringstream.cpp:33:20:33:31 | (const basic_ostream<char, char_traits<char>>)... | stringstream.cpp:33:23:33:28 | call to source |
| stringstream.cpp:33:20:33:31 | (const basic_ostream<char, char_traits<char>>)... | stringstream.cpp:33:23:33:30 | (const char *)... |
| stringstream.cpp:33:20:33:31 | (reference dereference) | stringstream.cpp:33:23:33:28 | call to source |
| stringstream.cpp:33:20:33:31 | (reference dereference) | stringstream.cpp:33:23:33:30 | (const char *)... |
| stringstream.cpp:33:20:33:31 | (reference to) | stringstream.cpp:33:23:33:28 | call to source |
| stringstream.cpp:33:20:33:31 | (reference to) | stringstream.cpp:33:23:33:30 | (const char *)... |
| stringstream.cpp:34:23:34:23 | call to operator<< | stringstream.cpp:34:14:34:19 | call to source |
| stringstream.cpp:34:23:34:23 | call to operator<< | stringstream.cpp:34:14:34:21 | (const char *)... |
| stringstream.cpp:34:23:34:31 | (const basic_ostream<char, char_traits<char>>)... | stringstream.cpp:34:14:34:19 | call to source |
| stringstream.cpp:34:23:34:31 | (const basic_ostream<char, char_traits<char>>)... | stringstream.cpp:34:14:34:21 | (const char *)... |
| stringstream.cpp:34:23:34:31 | (reference dereference) | stringstream.cpp:34:14:34:19 | call to source |
| stringstream.cpp:34:23:34:31 | (reference dereference) | stringstream.cpp:34:14:34:21 | (const char *)... |
| stringstream.cpp:34:23:34:31 | (reference to) | stringstream.cpp:34:14:34:19 | call to source |
| stringstream.cpp:34:23:34:31 | (reference to) | stringstream.cpp:34:14:34:21 | (const char *)... |
| stringstream.cpp:38:7:38:9 | Argument 0 indirection | stringstream.cpp:32:14:32:19 | call to source |
| stringstream.cpp:40:7:40:9 | Argument 0 indirection | stringstream.cpp:34:14:34:19 | call to source |
| stringstream.cpp:43:11:43:13 | call to str | stringstream.cpp:32:14:32:19 | call to source |
| stringstream.cpp:45:11:45:13 | call to str | stringstream.cpp:34:14:34:19 | call to source |
| stringstream.cpp:52:7:52:9 | Argument 0 indirection | stringstream.cpp:49:10:49:15 | call to source |
| stringstream.cpp:53:7:53:9 | Argument 0 indirection | stringstream.cpp:50:10:50:15 | call to source |
| stringstream.cpp:59:7:59:9 | Argument 0 indirection | stringstream.cpp:56:15:56:29 | call to source |
| stringstream.cpp:66:7:66:10 | Argument 0 indirection | stringstream.cpp:63:18:63:23 | call to source |
| stringstream.cpp:81:7:81:9 | Argument 0 indirection | stringstream.cpp:70:32:70:37 | source |
| stringstream.cpp:83:11:83:13 | call to str | stringstream.cpp:70:32:70:37 | source |
| stringstream.cpp:85:7:85:8 | v2 | stringstream.cpp:70:32:70:37 | source |
| stringstream.cpp:103:7:103:9 | Argument 0 indirection | stringstream.cpp:91:19:91:24 | call to source |
| stringstream.cpp:105:7:105:9 | Argument 0 indirection | stringstream.cpp:95:44:95:49 | call to source |
| stringstream.cpp:107:7:107:9 | Argument 0 indirection | stringstream.cpp:100:31:100:36 | call to source |
| stringstream.cpp:120:7:120:9 | Argument 0 indirection | stringstream.cpp:113:24:113:29 | call to source |
| stringstream.cpp:121:7:121:9 | Argument 0 indirection | stringstream.cpp:113:24:113:29 | call to source |
| stringstream.cpp:122:7:122:9 | Argument 0 indirection | stringstream.cpp:115:24:115:29 | call to source |
| stringstream.cpp:123:7:123:9 | Argument 0 indirection | stringstream.cpp:115:24:115:29 | call to source |
| stringstream.cpp:143:11:143:11 | call to operator<< | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:143:11:143:11 | call to operator<< | stringstream.cpp:143:14:143:21 | (const char *)... |
| stringstream.cpp:143:11:143:22 | (const basic_ostream<char, char_traits<char>>)... | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:143:11:143:22 | (const basic_ostream<char, char_traits<char>>)... | stringstream.cpp:143:14:143:21 | (const char *)... |
| stringstream.cpp:143:11:143:22 | (reference dereference) | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:143:11:143:22 | (reference dereference) | stringstream.cpp:143:14:143:21 | (const char *)... |
| stringstream.cpp:143:11:143:22 | (reference to) | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:143:11:143:22 | (reference to) | stringstream.cpp:143:14:143:21 | (const char *)... |
| stringstream.cpp:149:7:149:8 | Argument 0 indirection | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:150:7:150:8 | Argument 0 indirection | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:157:7:157:8 | call to basic_string | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:158:7:158:8 | call to basic_string | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:168:7:168:8 | call to basic_string | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:170:7:170:8 | call to basic_string | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:172:7:172:9 | call to basic_string | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:175:7:175:20 | ... = ... | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:177:7:177:21 | ... = ... | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:181:7:181:8 | c2 | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:183:7:183:8 | c4 | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:185:7:185:8 | c6 | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:197:10:197:12 | call to get | stringstream.cpp:196:18:196:32 | call to source |
| stringstream.cpp:219:7:219:8 | call to basic_string | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:220:7:220:8 | call to basic_string | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:227:7:227:8 | call to basic_string | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:228:7:228:8 | call to basic_string | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:231:7:231:8 | call to basic_string | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:239:7:239:8 | Argument 0 indirection | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:240:7:240:8 | Argument 0 indirection | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:247:7:247:8 | Argument 0 indirection | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:248:7:248:8 | Argument 0 indirection | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:251:7:251:8 | Argument 0 indirection | stringstream.cpp:203:24:203:29 | call to source |
| stringstream.cpp:263:7:263:8 | call to basic_string | stringstream.cpp:257:24:257:29 | call to source |
| structlikeclass.cpp:35:8:35:9 | s1 | structlikeclass.cpp:29:22:29:27 | call to source |
| structlikeclass.cpp:36:8:36:9 | s2 | structlikeclass.cpp:30:24:30:29 | call to source |
| structlikeclass.cpp:37:8:37:9 | s3 | structlikeclass.cpp:29:22:29:27 | call to source |
@@ -127,6 +236,7 @@
| taint.cpp:151:7:151:12 | call to select | taint.cpp:151:20:151:25 | call to source |
| taint.cpp:167:8:167:13 | call to source | taint.cpp:167:8:167:13 | call to source |
| taint.cpp:168:8:168:14 | tainted | taint.cpp:164:19:164:24 | call to source |
| taint.cpp:173:8:173:13 | Argument 0 indirection | taint.cpp:164:19:164:24 | call to source |
| taint.cpp:181:8:181:9 | * ... | taint.cpp:185:11:185:16 | call to source |
| taint.cpp:210:7:210:7 | x | taint.cpp:207:6:207:11 | call to source |
| taint.cpp:215:7:215:7 | x | taint.cpp:207:6:207:11 | call to source |
@@ -136,16 +246,56 @@
| taint.cpp:244:3:244:6 | t | taint.cpp:223:10:223:15 | call to source |
| taint.cpp:250:8:250:8 | a | taint.cpp:223:10:223:15 | call to source |
| taint.cpp:256:8:256:8 | (reference dereference) | taint.cpp:223:10:223:15 | call to source |
| taint.cpp:261:7:261:7 | w | taint.cpp:258:7:258:12 | call to source |
| taint.cpp:280:7:280:7 | t | taint.cpp:275:6:275:11 | call to source |
| taint.cpp:289:7:289:7 | t | taint.cpp:275:6:275:11 | call to source |
| taint.cpp:290:7:290:7 | x | taint.cpp:275:6:275:11 | call to source |
| taint.cpp:291:7:291:7 | y | taint.cpp:275:6:275:11 | call to source |
| taint.cpp:337:7:337:7 | t | taint.cpp:330:6:330:11 | call to source |
| taint.cpp:350:7:350:7 | t | taint.cpp:330:6:330:11 | call to source |
| taint.cpp:351:7:351:7 | a | taint.cpp:330:6:330:11 | call to source |
| taint.cpp:352:7:352:7 | b | taint.cpp:330:6:330:11 | call to source |
| taint.cpp:353:7:353:7 | c | taint.cpp:330:6:330:11 | call to source |
| taint.cpp:354:7:354:7 | d | taint.cpp:330:6:330:11 | call to source |
| taint.cpp:382:7:382:7 | a | taint.cpp:377:23:377:28 | source |
| taint.cpp:429:7:429:7 | b | taint.cpp:428:13:428:18 | call to source |
| taint.cpp:430:9:430:14 | member | taint.cpp:428:13:428:18 | call to source |
| taint.cpp:465:7:465:7 | x | taint.cpp:462:6:462:11 | call to source |
| taint.cpp:470:7:470:7 | x | taint.cpp:462:6:462:11 | call to source |
| taint.cpp:471:7:471:7 | y | taint.cpp:462:6:462:11 | call to source |
| taint.cpp:485:7:485:10 | line | taint.cpp:480:26:480:32 | source1 |
| vector.cpp:20:8:20:8 | x | vector.cpp:16:43:16:49 | source1 |
| vector.cpp:24:8:24:8 | call to operator* | vector.cpp:16:43:16:49 | source1 |
| vector.cpp:24:8:24:11 | (reference dereference) | vector.cpp:16:43:16:49 | source1 |
| vector.cpp:28:8:28:8 | (reference dereference) | vector.cpp:16:43:16:49 | source1 |
| vector.cpp:28:8:28:8 | x | vector.cpp:16:43:16:49 | source1 |
| vector.cpp:33:8:33:8 | (reference dereference) | vector.cpp:16:43:16:49 | source1 |
| vector.cpp:33:8:33:8 | x | vector.cpp:16:43:16:49 | source1 |
| vector.cpp:70:7:70:8 | Argument 0 indirection | vector.cpp:69:15:69:20 | call to source |
| vector.cpp:83:7:83:8 | Argument 0 indirection | vector.cpp:81:17:81:22 | call to source |
| vector.cpp:109:7:109:8 | Argument 0 indirection | vector.cpp:106:15:106:20 | call to source |
| vector.cpp:112:7:112:8 | Argument 0 indirection | vector.cpp:107:15:107:20 | call to source |
| vector.cpp:117:7:117:8 | Argument 0 indirection | vector.cpp:106:15:106:20 | call to source |
| vector.cpp:118:7:118:8 | Argument 0 indirection | vector.cpp:106:15:106:20 | call to source |
| vector.cpp:119:7:119:8 | Argument 0 indirection | vector.cpp:107:15:107:20 | call to source |
| vector.cpp:120:7:120:8 | Argument 0 indirection | vector.cpp:107:15:107:20 | call to source |
| vector.cpp:130:7:130:8 | Argument 0 indirection | vector.cpp:126:15:126:20 | call to source |
| vector.cpp:131:7:131:8 | Argument 0 indirection | vector.cpp:127:15:127:20 | call to source |
| vector.cpp:132:7:132:8 | Argument 0 indirection | vector.cpp:128:15:128:20 | call to source |
| vector.cpp:139:7:139:8 | Argument 0 indirection | vector.cpp:126:15:126:20 | call to source |
| vector.cpp:140:7:140:8 | Argument 0 indirection | vector.cpp:127:15:127:20 | call to source |
| vector.cpp:141:7:141:8 | Argument 0 indirection | vector.cpp:128:15:128:20 | call to source |
| vector.cpp:162:8:162:15 | access to array | vector.cpp:161:14:161:19 | call to source |
| vector.cpp:242:7:242:8 | Argument 0 indirection | vector.cpp:238:17:238:30 | call to source |
| vector.cpp:243:7:243:8 | Argument 0 indirection | vector.cpp:239:15:239:20 | call to source |
| vector.cpp:258:8:258:9 | Argument 0 indirection | vector.cpp:239:15:239:20 | call to source |
| vector.cpp:259:8:259:9 | Argument 0 indirection | vector.cpp:239:15:239:20 | call to source |
| vector.cpp:260:8:260:9 | Argument 0 indirection | vector.cpp:239:15:239:20 | call to source |
| vector.cpp:273:8:273:9 | Argument 0 indirection | vector.cpp:269:18:269:31 | call to source |
| vector.cpp:274:8:274:9 | Argument 0 indirection | vector.cpp:270:18:270:35 | call to source |
| vector.cpp:275:8:275:9 | Argument 0 indirection | vector.cpp:271:18:271:34 | call to source |
| vector.cpp:285:7:285:8 | Argument 0 indirection | vector.cpp:284:15:284:20 | call to source |
| vector.cpp:309:7:309:7 | Argument 0 indirection | vector.cpp:303:14:303:19 | call to source |
| vector.cpp:312:7:312:7 | Argument 0 indirection | vector.cpp:303:14:303:19 | call to source |
| vector.cpp:324:7:324:8 | Argument 0 indirection | vector.cpp:318:15:318:20 | call to source |
| vector.cpp:326:7:326:8 | Argument 0 indirection | vector.cpp:318:15:318:20 | call to source |

View File

@@ -21,7 +21,7 @@ void test_range_based_for_loop_vector(int source1) {
}
for(std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
sink(*it); // tainted
sink(*it); // tainted [NOT DETECTED by IR]
}
for(int& x : v) {
@@ -159,7 +159,7 @@ void test_nested_vectors()
sink(aa[0][0]);
aa[0][0] = source();
sink(aa[0][0]); // tainted [IR ONLY]
sink(aa[0][0]); // tainted
}
{
@@ -325,3 +325,77 @@ void test_constructors_more() {
sink(v3);
sink(v4); // tainted
}
void taint_vector_output_iterator(std::vector<int>::iterator iter) {
*iter = source();
}
void vector_iterator_assign_wrapper(std::vector<int>::iterator iter, int i) {
*iter = i;
}
void test_vector_output_iterator(int b) {
std::vector<int> v1(10), v2(10), v3(10), v4(10), v5(10), v6(10), v7(10), v8(10), v9(10), v10(10), v11(10);
std::vector<int>::iterator i1 = v1.begin();
*i1 = source();
sink(v1); // tainted [NOT DETECTED by IR]
for(std::vector<int>::iterator it = v2.begin(); it != v2.end(); ++it) {
*it = source();
}
sink(v2); // tainted [NOT DETECTED by IR]
for(int& x : v3) {
x = source();
}
sink(v3); // tainted [NOT DETECTED]
for(std::vector<int>::iterator it = v4.begin(); it != v4.end(); ++it) {
taint_vector_output_iterator(it);
}
sink(v4); // tainted [NOT DETECTED by IR]
std::vector<int>::iterator i5 = v5.begin();
*i5 = source();
sink(v5); // tainted [NOT DETECTED by IR]
*i5 = 1;
sink(v5); // tainted [NOT DETECTED by IR]
std::vector<int>::iterator i6 = v6.begin();
*i6 = source();
sink(v6); // tainted [NOT DETECTED by IR]
v6 = std::vector<int>(10);
sink(v6); // [FALSE POSITIVE in AST]
std::vector<int>::iterator i7 = v7.begin();
if(b) {
*i7 = source();
sink(v7); // tainted [NOT DETECTED by IR]
} else {
*i7 = 1;
sink(v7);
}
sink(v7); // tainted [NOT DETECTED by IR]
std::vector<int>::iterator i8 = v8.begin();
*i8 = source();
sink(v8); // tainted [NOT DETECTED by IR]
*i8 = 1;
sink(v8);
std::vector<int>::iterator i9 = v9.begin();
*i9 = source();
taint_vector_output_iterator(i9);
sink(v9);
std::vector<int>::iterator i10 = v10.begin();
vector_iterator_assign_wrapper(i10, 10);
sink(v10);
std::vector<int>::iterator i11 = v11.begin();
vector_iterator_assign_wrapper(i11, source());
sink(v11); // tainted [NOT DETECTED by IR]
}

View File

@@ -13,9 +13,9 @@
| captures.cpp:3:5:3:5 | (constructor) |
| captures.cpp:3:5:3:5 | (constructor) |
| captures.cpp:3:5:3:5 | (constructor) |
| captures.cpp:3:5:3:5 | declaration of (null) |
| captures.cpp:3:5:3:5 | declaration of (null) |
| captures.cpp:3:5:3:5 | definition of (null) |
| captures.cpp:3:5:3:5 | declaration of (constructor) |
| captures.cpp:3:5:3:5 | declaration of (constructor) |
| captures.cpp:3:5:3:5 | definition of (constructor) |
| captures.cpp:3:5:3:5 | definition of operator= |
| captures.cpp:3:5:3:5 | operator= |
| captures.cpp:3:5:5:5 | [...](...){...} |
@@ -50,9 +50,9 @@
| captures.cpp:9:5:9:5 | (constructor) |
| captures.cpp:9:5:9:5 | (constructor) |
| captures.cpp:9:5:9:5 | (constructor) |
| captures.cpp:9:5:9:5 | declaration of (null) |
| captures.cpp:9:5:9:5 | declaration of (null) |
| captures.cpp:9:5:9:5 | definition of (null) |
| captures.cpp:9:5:9:5 | declaration of (constructor) |
| captures.cpp:9:5:9:5 | declaration of (constructor) |
| captures.cpp:9:5:9:5 | definition of (constructor) |
| captures.cpp:9:5:9:5 | definition of operator= |
| captures.cpp:9:5:9:5 | operator= |
| captures.cpp:9:5:11:5 | [...](...){...} |
@@ -87,9 +87,9 @@
| captures.cpp:15:5:15:5 | (constructor) |
| captures.cpp:15:5:15:5 | (constructor) |
| captures.cpp:15:5:15:5 | (constructor) |
| captures.cpp:15:5:15:5 | declaration of (null) |
| captures.cpp:15:5:15:5 | declaration of (null) |
| captures.cpp:15:5:15:5 | definition of (null) |
| captures.cpp:15:5:15:5 | declaration of (constructor) |
| captures.cpp:15:5:15:5 | declaration of (constructor) |
| captures.cpp:15:5:15:5 | definition of (constructor) |
| captures.cpp:15:5:15:5 | definition of operator= |
| captures.cpp:15:5:15:5 | operator= |
| captures.cpp:15:5:17:5 | [...](...){...} |
@@ -129,9 +129,9 @@
| captures.cpp:22:19:22:19 | Unknown literal |
| captures.cpp:22:19:22:19 | constructor init of field x |
| captures.cpp:22:19:22:19 | constructor init of field y |
| captures.cpp:22:19:22:19 | declaration of (null) |
| captures.cpp:22:19:22:19 | definition of (null) |
| captures.cpp:22:19:22:19 | definition of (null) |
| captures.cpp:22:19:22:19 | declaration of (constructor) |
| captures.cpp:22:19:22:19 | definition of (constructor) |
| captures.cpp:22:19:22:19 | definition of (constructor) |
| captures.cpp:22:19:22:19 | definition of operator= |
| captures.cpp:22:19:22:19 | operator= |
| captures.cpp:22:19:22:19 | return ... |
@@ -187,9 +187,9 @@
| end_pos.cpp:9:15:9:15 | (constructor) |
| end_pos.cpp:9:15:9:15 | Unknown literal |
| end_pos.cpp:9:15:9:15 | constructor init of field ii |
| end_pos.cpp:9:15:9:15 | declaration of (null) |
| end_pos.cpp:9:15:9:15 | definition of (null) |
| end_pos.cpp:9:15:9:15 | definition of (null) |
| end_pos.cpp:9:15:9:15 | declaration of (constructor) |
| end_pos.cpp:9:15:9:15 | definition of (constructor) |
| end_pos.cpp:9:15:9:15 | definition of (constructor) |
| end_pos.cpp:9:15:9:15 | definition of operator= |
| end_pos.cpp:9:15:9:15 | operator= |
| end_pos.cpp:9:15:9:15 | return ... |

View File

@@ -2,8 +2,8 @@
| copy_from_prototype.cpp:3:7:3:7 | a | a<int>::a(const a<int> &) -> void | copy_from_prototype.cpp:3:7:3:7 | a<int> | <no expr> |
| copy_from_prototype.cpp:3:7:3:7 | operator= | a<int>::operator=(a<int> &&) -> a<int> & | copy_from_prototype.cpp:3:7:3:7 | a<int> | <no expr> |
| copy_from_prototype.cpp:3:7:3:7 | operator= | a<int>::operator=(const a<int> &) -> a<int> & | copy_from_prototype.cpp:3:7:3:7 | a<int> | <no expr> |
| copy_from_prototype.cpp:4:26:4:26 | a | a<<unnamed>>::a<(unnamed)>() -> void | copy_from_prototype.cpp:3:7:3:7 | a<<unnamed>> | 123 |
| copy_from_prototype.cpp:4:26:4:26 | a | a<int>::a<(unnamed)>() -> void | copy_from_prototype.cpp:3:7:3:7 | a<int> | <no expr> |
| copy_from_prototype.cpp:4:26:4:26 | a | a<<unnamed>>::a<(unnamed template parameter)>() -> void | copy_from_prototype.cpp:3:7:3:7 | a<<unnamed>> | 123 |
| copy_from_prototype.cpp:4:26:4:26 | a | a<int>::a<(unnamed template parameter)>() -> void | copy_from_prototype.cpp:3:7:3:7 | a<int> | <no expr> |
| copy_from_prototype.cpp:7:7:7:7 | b | b::b() -> void | copy_from_prototype.cpp:7:7:7:7 | b | <no expr> |
| copy_from_prototype.cpp:7:7:7:7 | b | b::b(b &&) -> void | copy_from_prototype.cpp:7:7:7:7 | b | <no expr> |
| copy_from_prototype.cpp:7:7:7:7 | b | b::b(const b &) -> void | copy_from_prototype.cpp:7:7:7:7 | b | <no expr> |
@@ -13,8 +13,8 @@
| copy_from_prototype.cpp:13:7:13:7 | c | c<int>::c(const c<int> &) -> void | copy_from_prototype.cpp:13:7:13:7 | c<int> | <no expr> |
| copy_from_prototype.cpp:13:7:13:7 | operator= | c<int>::operator=(c<int> &&) -> c<int> & | copy_from_prototype.cpp:13:7:13:7 | c<int> | <no expr> |
| copy_from_prototype.cpp:13:7:13:7 | operator= | c<int>::operator=(const c<int> &) -> c<int> & | copy_from_prototype.cpp:13:7:13:7 | c<int> | <no expr> |
| copy_from_prototype.cpp:14:26:14:26 | c | c<T>::c<(unnamed)>() -> void | copy_from_prototype.cpp:13:7:13:7 | c<T> | X |
| copy_from_prototype.cpp:14:26:14:26 | c | c<int>::c<(unnamed)>() -> void | copy_from_prototype.cpp:13:7:13:7 | c<int> | <no expr> |
| copy_from_prototype.cpp:14:26:14:26 | c | c<T>::c<(unnamed template parameter)>() -> void | copy_from_prototype.cpp:13:7:13:7 | c<T> | X |
| copy_from_prototype.cpp:14:26:14:26 | c | c<int>::c<(unnamed template parameter)>() -> void | copy_from_prototype.cpp:13:7:13:7 | c<int> | <no expr> |
| copy_from_prototype.cpp:17:7:17:7 | d | d::d() -> void | copy_from_prototype.cpp:17:7:17:7 | d | <no expr> |
| copy_from_prototype.cpp:17:7:17:7 | d | d::d(const d &) -> void | copy_from_prototype.cpp:17:7:17:7 | d | <no expr> |
| copy_from_prototype.cpp:17:7:17:7 | d | d::d(d &&) -> void | copy_from_prototype.cpp:17:7:17:7 | d | <no expr> |
@@ -24,7 +24,7 @@
| copy_from_prototype.cpp:22:8:22:8 | e | e<int>::e(e<int> &&) -> void | copy_from_prototype.cpp:22:8:22:8 | e<int> | <no expr> |
| copy_from_prototype.cpp:22:8:22:8 | operator= | e<int>::operator=(const e<int> &) -> e<int> & | copy_from_prototype.cpp:22:8:22:8 | e<int> | <no expr> |
| copy_from_prototype.cpp:22:8:22:8 | operator= | e<int>::operator=(e<int> &&) -> e<int> & | copy_from_prototype.cpp:22:8:22:8 | e<int> | <no expr> |
| copy_from_prototype.cpp:23:26:23:26 | e | e<T>::e<(unnamed)>() -> void | copy_from_prototype.cpp:22:8:22:8 | e<T> | 456 |
| copy_from_prototype.cpp:26:35:26:43 | e | e<int>::e<(unnamed)>() -> void | copy_from_prototype.cpp:22:8:22:8 | e<int> | 456 |
| copy_from_prototype.cpp:23:26:23:26 | e | e<T>::e<(unnamed template parameter)>() -> void | copy_from_prototype.cpp:22:8:22:8 | e<T> | 456 |
| copy_from_prototype.cpp:26:35:26:43 | e | e<int>::e<(unnamed template parameter)>() -> void | copy_from_prototype.cpp:22:8:22:8 | e<int> | 456 |
| file://:0:0:0:0 | operator= | __va_list_tag::operator=(__va_list_tag &&) -> __va_list_tag & | file://:0:0:0:0 | __va_list_tag | <none> |
| file://:0:0:0:0 | operator= | __va_list_tag::operator=(const __va_list_tag &) -> __va_list_tag & | file://:0:0:0:0 | __va_list_tag | <none> |

View File

@@ -78,8 +78,6 @@
| copy.cpp:111:9:111:9 | MoveAssign | deleted | |
| copy.cpp:111:9:111:9 | operator= | deleted | |
| copy.cpp:113:17:113:25 | operator= | | |
| copy.cpp:120:9:120:9 | OnlyCtor | | |
| copy.cpp:120:9:120:9 | OnlyCtor | | |
| copy.cpp:120:9:120:9 | OnlyCtor | deleted | |
| copy.cpp:120:9:120:9 | operator= | deleted | |
| copy.cpp:126:11:126:19 | operator= | | |

View File

@@ -539,8 +539,6 @@ uniqueNodeLocation
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
| file://:0:0:0:0 | p#1 | Node should have one location but has 0. |
| file://:0:0:0:0 | p#1 | Node should have one location but has 0. |
| file://:0:0:0:0 | p#1 | Node should have one location but has 0. |
@@ -1418,7 +1416,7 @@ uniqueNodeLocation
| 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
| Nodes without location: 36 |
| Nodes without location: 34 |
uniqueNodeToString
| break_labels.c:2:11:2:11 | i | Node should have one toString but has 2. |
| break_labels.c:2:11:2:11 | i | Node should have one toString but has 2. |

View File

@@ -1,7 +1,7 @@
| file://:0:0:0:0 | __va_list_tag | <none> |
| test.cpp:3:8:3:9 | s1<<expression>> | {...} |
| test.cpp:3:8:3:9 | s1<<unnamed>> | (null) |
| test.cpp:3:8:3:9 | s1<<unnamed>> | (unnamed template parameter constant) |
| test.cpp:5:8:5:9 | s2<T> | T |
| test.cpp:5:8:5:9 | s2<T> | T |
| test.cpp:7:8:7:9 | s3<T, <unnamed>> | (unnamed) |
| test.cpp:7:8:7:9 | s3<T, <unnamed>> | (unnamed template parameter) |
| test.cpp:7:8:7:9 | s3<T, <unnamed>> | T |

View File

@@ -7,7 +7,7 @@
| decls.cpp:4:30:4:34 | p#0 |
| decls.cpp:4:30:4:34 | p#0 |
| decls.cpp:6:17:6:17 | f |
| decls.cpp:8:18:8:18 | (unnamed) |
| decls.cpp:8:18:8:18 | (unnamed template parameter) |
| decls.cpp:8:25:8:25 | g |
| file://:0:0:0:0 | __va_list_tag |
| file://:0:0:0:0 | auto |

View File

@@ -1,6 +1,6 @@
| file://:0:0:0:0 | | Other |
| file://:0:0:0:0 | (global namespace) | Other |
| file://:0:0:0:0 | <unnamed> | Other |
| file://:0:0:0:0 | (unnamed global/namespace variable) | Other |
| file://:0:0:0:0 | _Complex __float128 | Other |
| file://:0:0:0:0 | _Complex double | Other |
| file://:0:0:0:0 | _Complex float | Other |
@@ -111,8 +111,8 @@
| test.c:0:0:0:0 | test.c | Other |
| test.c:2:6:2:6 | a | Other |
| test.c:2:6:2:6 | definition of a | Other |
| test.c:2:10:2:18 | <unnamed> | Variable access |
| test.c:2:10:2:18 | (unnamed global/namespace variable) | Variable access |
| test.c:2:10:2:18 | array to pointer conversion | Other |
| test.c:2:10:2:18 | initializer for a | Other |
| test.c:2:17:2:18 | initializer for <unnamed> | Other |
| test.c:2:17:2:18 | initializer for (unnamed global/namespace variable) | Other |
| test.c:2:17:2:18 | {...} | Other |

View File

@@ -5,6 +5,10 @@ edges
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array |
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array |
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array |
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array |
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array |
| tests.c:28:22:28:28 | access to array | tests.c:28:22:28:28 | (const char *)... |
| tests.c:28:22:28:28 | access to array | tests.c:28:22:28:28 | access to array |
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array |
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array |
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array |
@@ -15,6 +19,10 @@ edges
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array |
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array |
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array |
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array |
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array |
| tests.c:34:10:34:16 | access to array | tests.c:34:10:34:16 | (const char *)... |
| tests.c:34:10:34:16 | access to array | tests.c:34:10:34:16 | access to array |
nodes
| tests.c:28:22:28:25 | argv | semmle.label | argv |
| tests.c:28:22:28:25 | argv | semmle.label | argv |

View File

@@ -5,6 +5,10 @@ edges
| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array |
| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array |
| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array |
| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array |
| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array |
| argvLocal.c:95:9:95:15 | access to array | argvLocal.c:95:9:95:15 | (const char *)... |
| argvLocal.c:95:9:95:15 | access to array | argvLocal.c:95:9:95:15 | access to array |
| argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array |
| argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array |
| argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array |
@@ -35,6 +39,8 @@ edges
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array |
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array |
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array |
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array |
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array |
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array |
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array |
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array |
@@ -45,10 +51,16 @@ edges
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... |
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... |
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... |
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... |
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... |
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... |
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... |
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... |
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... |
| argvLocal.c:106:9:106:13 | access to array | argvLocal.c:106:9:106:13 | (const char *)... |
| argvLocal.c:106:9:106:13 | access to array | argvLocal.c:106:9:106:13 | access to array |
| argvLocal.c:110:9:110:11 | * ... | argvLocal.c:110:9:110:11 | (const char *)... |
| argvLocal.c:110:9:110:11 | * ... | argvLocal.c:110:9:110:11 | * ... |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | (const char *)... |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | (const char *)... |
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 |

View File

@@ -13,6 +13,8 @@ edges
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 |
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 |
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 |
| globalVars.c:11:22:11:25 | *argv | globalVars.c:12:2:12:15 | Store |
| globalVars.c:11:22:11:25 | argv | globalVars.c:11:22:11:25 | *argv |
| globalVars.c:11:22:11:25 | argv | globalVars.c:12:2:12:15 | Store |
| globalVars.c:12:2:12:15 | Store | globalVars.c:8:7:8:10 | copy |
| globalVars.c:15:21:15:23 | val | globalVars.c:16:2:16:12 | Store |
@@ -29,6 +31,7 @@ edges
nodes
| globalVars.c:8:7:8:10 | copy | semmle.label | copy |
| globalVars.c:9:7:9:11 | copy2 | semmle.label | copy2 |
| globalVars.c:11:22:11:25 | *argv | semmle.label | *argv |
| globalVars.c:11:22:11:25 | argv | semmle.label | argv |
| globalVars.c:12:2:12:15 | Store | semmle.label | Store |
| globalVars.c:15:21:15:23 | val | semmle.label | val |

View File

@@ -59,18 +59,21 @@ edges
| test.cpp:227:24:227:37 | (const char *)... | test.cpp:237:10:237:19 | (size_t)... |
| test.cpp:235:11:235:20 | (size_t)... | test.cpp:214:23:214:23 | s |
| test.cpp:237:10:237:19 | (size_t)... | test.cpp:220:21:220:21 | s |
| test.cpp:241:2:241:32 | Chi | test.cpp:279:17:279:20 | get_size output argument |
| test.cpp:241:2:241:32 | Chi | test.cpp:295:18:295:21 | get_size output argument |
| test.cpp:241:18:241:23 | call to getenv | test.cpp:241:2:241:32 | Chi |
| test.cpp:241:18:241:31 | (const char *)... | test.cpp:241:2:241:32 | Chi |
| test.cpp:241:2:241:32 | Chi [array content] | test.cpp:279:17:279:20 | get_size output argument [array content] |
| test.cpp:241:2:241:32 | Chi [array content] | test.cpp:295:18:295:21 | get_size output argument [array content] |
| test.cpp:241:2:241:32 | Store | test.cpp:241:2:241:32 | Chi [array content] |
| test.cpp:241:18:241:23 | call to getenv | test.cpp:241:2:241:32 | Store |
| test.cpp:241:18:241:31 | (const char *)... | test.cpp:241:2:241:32 | Store |
| test.cpp:249:20:249:25 | call to getenv | test.cpp:253:11:253:29 | ... * ... |
| test.cpp:249:20:249:25 | call to getenv | test.cpp:253:11:253:29 | ... * ... |
| test.cpp:249:20:249:33 | (const char *)... | test.cpp:253:11:253:29 | ... * ... |
| test.cpp:249:20:249:33 | (const char *)... | test.cpp:253:11:253:29 | ... * ... |
| test.cpp:279:17:279:20 | get_size output argument | test.cpp:281:11:281:28 | ... * ... |
| test.cpp:279:17:279:20 | get_size output argument | test.cpp:281:11:281:28 | ... * ... |
| test.cpp:295:18:295:21 | get_size output argument | test.cpp:298:10:298:27 | ... * ... |
| test.cpp:295:18:295:21 | get_size output argument | test.cpp:298:10:298:27 | ... * ... |
| test.cpp:279:17:279:20 | Chi | test.cpp:281:11:281:28 | ... * ... |
| test.cpp:279:17:279:20 | Chi | test.cpp:281:11:281:28 | ... * ... |
| test.cpp:279:17:279:20 | get_size output argument [array content] | test.cpp:279:17:279:20 | Chi |
| test.cpp:295:18:295:21 | Chi | test.cpp:298:10:298:27 | ... * ... |
| test.cpp:295:18:295:21 | Chi | test.cpp:298:10:298:27 | ... * ... |
| test.cpp:295:18:295:21 | get_size output argument [array content] | test.cpp:295:18:295:21 | Chi |
| test.cpp:301:19:301:24 | call to getenv | test.cpp:305:11:305:28 | ... * ... |
| test.cpp:301:19:301:24 | call to getenv | test.cpp:305:11:305:28 | ... * ... |
| test.cpp:301:19:301:32 | (const char *)... | test.cpp:305:11:305:28 | ... * ... |
@@ -142,7 +145,8 @@ nodes
| test.cpp:231:9:231:24 | call to get_tainted_size | semmle.label | call to get_tainted_size |
| test.cpp:235:11:235:20 | (size_t)... | semmle.label | (size_t)... |
| test.cpp:237:10:237:19 | (size_t)... | semmle.label | (size_t)... |
| test.cpp:241:2:241:32 | Chi | semmle.label | Chi |
| test.cpp:241:2:241:32 | Chi [array content] | semmle.label | Chi [array content] |
| test.cpp:241:2:241:32 | Store | semmle.label | Store |
| test.cpp:241:18:241:23 | call to getenv | semmle.label | call to getenv |
| test.cpp:241:18:241:31 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:249:20:249:25 | call to getenv | semmle.label | call to getenv |
@@ -150,11 +154,13 @@ nodes
| test.cpp:253:11:253:29 | ... * ... | semmle.label | ... * ... |
| test.cpp:253:11:253:29 | ... * ... | semmle.label | ... * ... |
| test.cpp:253:11:253:29 | ... * ... | semmle.label | ... * ... |
| test.cpp:279:17:279:20 | get_size output argument | semmle.label | get_size output argument |
| test.cpp:279:17:279:20 | Chi | semmle.label | Chi |
| test.cpp:279:17:279:20 | get_size output argument [array content] | semmle.label | get_size output argument [array content] |
| test.cpp:281:11:281:28 | ... * ... | semmle.label | ... * ... |
| test.cpp:281:11:281:28 | ... * ... | semmle.label | ... * ... |
| test.cpp:281:11:281:28 | ... * ... | semmle.label | ... * ... |
| test.cpp:295:18:295:21 | get_size output argument | semmle.label | get_size output argument |
| test.cpp:295:18:295:21 | Chi | semmle.label | Chi |
| test.cpp:295:18:295:21 | get_size output argument [array content] | semmle.label | get_size output argument [array content] |
| test.cpp:298:10:298:27 | ... * ... | semmle.label | ... * ... |
| test.cpp:298:10:298:27 | ... * ... | semmle.label | ... * ... |
| test.cpp:298:10:298:27 | ... * ... | semmle.label | ... * ... |

View File

@@ -1,4 +1,5 @@
| test2.cpp:14:11:14:15 | ... * ... | $@ flows to here and is used in an expression which might overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
| test2.cpp:15:11:15:19 | ... * ... | $@ flows to here and is used in an expression which might overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
| test2.cpp:16:11:16:21 | ... * ... | $@ flows to here and is used in an expression which might overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
| test2.cpp:17:11:17:22 | ... * ... | $@ flows to here and is used in an expression which might overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
| test3.c:12:31:12:34 | * ... | $@ flows to here and is used in an expression which might overflow negatively. | test3.c:11:15:11:18 | argv | User-provided value |

View File

@@ -12,7 +12,7 @@ typedef struct _myStruct {
void test2_sink(s64 v, MyStruct s, MyStruct &s_r, MyStruct *s_p)
{
s64 v1 = v * 2; // bad
s64 v2 = s.val * 2; // bad [NOT DETECTED]
s64 v2 = s.val * 2; // bad
s64 v3 = s_r.val * 2; // bad
s64 v4 = s_p->val * 2; // bad
}

View File

@@ -42,18 +42,22 @@ edges
| test.cpp:8:9:8:12 | Store | test.cpp:24:11:24:18 | call to get_rand |
| test.cpp:8:9:8:12 | call to rand | test.cpp:8:9:8:12 | Store |
| test.cpp:8:9:8:12 | call to rand | test.cpp:8:9:8:12 | Store |
| test.cpp:13:2:13:15 | Chi | test.cpp:30:13:30:14 | get_rand2 output argument |
| test.cpp:13:10:13:13 | call to rand | test.cpp:13:2:13:15 | Chi |
| test.cpp:13:10:13:13 | call to rand | test.cpp:13:2:13:15 | Chi |
| test.cpp:18:2:18:14 | Chi | test.cpp:36:13:36:13 | get_rand3 output argument |
| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:14 | Chi |
| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:14 | Chi |
| test.cpp:13:2:13:15 | Chi [array content] | test.cpp:30:13:30:14 | get_rand2 output argument [array content] |
| test.cpp:13:2:13:15 | Store | test.cpp:13:2:13:15 | Chi [array content] |
| test.cpp:13:10:13:13 | call to rand | test.cpp:13:2:13:15 | Store |
| test.cpp:13:10:13:13 | call to rand | test.cpp:13:2:13:15 | Store |
| test.cpp:18:2:18:14 | Chi [array content] | test.cpp:36:13:36:13 | get_rand3 output argument [array content] |
| test.cpp:18:2:18:14 | Store | test.cpp:18:2:18:14 | Chi [array content] |
| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:14 | Store |
| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:14 | Store |
| test.cpp:24:11:24:18 | call to get_rand | test.cpp:25:7:25:7 | r |
| test.cpp:24:11:24:18 | call to get_rand | test.cpp:25:7:25:7 | r |
| test.cpp:30:13:30:14 | get_rand2 output argument | test.cpp:31:7:31:7 | r |
| test.cpp:30:13:30:14 | get_rand2 output argument | test.cpp:31:7:31:7 | r |
| test.cpp:36:13:36:13 | get_rand3 output argument | test.cpp:37:7:37:7 | r |
| test.cpp:36:13:36:13 | get_rand3 output argument | test.cpp:37:7:37:7 | r |
| test.cpp:30:13:30:14 | Chi | test.cpp:31:7:31:7 | r |
| test.cpp:30:13:30:14 | Chi | test.cpp:31:7:31:7 | r |
| test.cpp:30:13:30:14 | get_rand2 output argument [array content] | test.cpp:30:13:30:14 | Chi |
| test.cpp:36:13:36:13 | Chi | test.cpp:37:7:37:7 | r |
| test.cpp:36:13:36:13 | Chi | test.cpp:37:7:37:7 | r |
| test.cpp:36:13:36:13 | get_rand3 output argument [array content] | test.cpp:36:13:36:13 | Chi |
nodes
| test.c:18:13:18:16 | call to rand | semmle.label | call to rand |
| test.c:18:13:18:16 | call to rand | semmle.label | call to rand |
@@ -106,21 +110,25 @@ nodes
| test.cpp:8:9:8:12 | Store | semmle.label | Store |
| test.cpp:8:9:8:12 | call to rand | semmle.label | call to rand |
| test.cpp:8:9:8:12 | call to rand | semmle.label | call to rand |
| test.cpp:13:2:13:15 | Chi | semmle.label | Chi |
| test.cpp:13:2:13:15 | Chi [array content] | semmle.label | Chi [array content] |
| test.cpp:13:2:13:15 | Store | semmle.label | Store |
| test.cpp:13:10:13:13 | call to rand | semmle.label | call to rand |
| test.cpp:13:10:13:13 | call to rand | semmle.label | call to rand |
| test.cpp:18:2:18:14 | Chi | semmle.label | Chi |
| test.cpp:18:2:18:14 | Chi [array content] | semmle.label | Chi [array content] |
| test.cpp:18:2:18:14 | Store | semmle.label | Store |
| test.cpp:18:9:18:12 | call to rand | semmle.label | call to rand |
| test.cpp:18:9:18:12 | call to rand | semmle.label | call to rand |
| test.cpp:24:11:24:18 | call to get_rand | semmle.label | call to get_rand |
| test.cpp:25:7:25:7 | r | semmle.label | r |
| test.cpp:25:7:25:7 | r | semmle.label | r |
| test.cpp:25:7:25:7 | r | semmle.label | r |
| test.cpp:30:13:30:14 | get_rand2 output argument | semmle.label | get_rand2 output argument |
| test.cpp:30:13:30:14 | Chi | semmle.label | Chi |
| test.cpp:30:13:30:14 | get_rand2 output argument [array content] | semmle.label | get_rand2 output argument [array content] |
| test.cpp:31:7:31:7 | r | semmle.label | r |
| test.cpp:31:7:31:7 | r | semmle.label | r |
| test.cpp:31:7:31:7 | r | semmle.label | r |
| test.cpp:36:13:36:13 | get_rand3 output argument | semmle.label | get_rand3 output argument |
| test.cpp:36:13:36:13 | Chi | semmle.label | Chi |
| test.cpp:36:13:36:13 | get_rand3 output argument [array content] | semmle.label | get_rand3 output argument [array content] |
| test.cpp:37:7:37:7 | r | semmle.label | r |
| test.cpp:37:7:37:7 | r | semmle.label | r |
| test.cpp:37:7:37:7 | r | semmle.label | r |

View File

@@ -363,7 +363,6 @@ namespace Semmle.Autobuild.CSharp.Tests
string cwd = @"C:\Project")
{
string codeqlUpperLanguage = Language.CSharp.UpperCaseName;
Actions.GetEnvironmentVariable[$"CODEQL_AUTOBUILDER_{codeqlUpperLanguage}_NO_INDEXING"] = "false";
Actions.GetEnvironmentVariable[$"CODEQL_EXTRACTOR_{codeqlUpperLanguage}_TRAP_DIR"] = "";
Actions.GetEnvironmentVariable[$"CODEQL_EXTRACTOR_{codeqlUpperLanguage}_SOURCE_ARCHIVE_DIR"] = "";
Actions.GetEnvironmentVariable[$"CODEQL_EXTRACTOR_{codeqlUpperLanguage}_ROOT"] = $@"C:\codeql\{codeqlUpperLanguage.ToLowerInvariant()}";
@@ -400,8 +399,6 @@ namespace Semmle.Autobuild.CSharp.Tests
Actions.RunProcess[@"cmd.exe /C dotnet clean C:\Project\test.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C dotnet restore C:\Project\test.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto dotnet build --no-incremental C:\Project\test.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
Actions.FileExists[@"C:\Project\test.csproj"] = true;
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
@@ -419,7 +416,7 @@ namespace Semmle.Autobuild.CSharp.Tests
Actions.LoadXml[@"C:\Project\test.csproj"] = xml;
var autobuilder = CreateAutoBuilder(true);
TestAutobuilderScript(autobuilder, 0, 6);
TestAutobuilderScript(autobuilder, 0, 4);
}
[Fact]
@@ -432,8 +429,6 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.RunProcess[@"dotnet clean C:\Project/test.csproj"] = 0;
Actions.RunProcess[@"dotnet restore C:\Project/test.csproj"] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project/test.csproj"] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
Actions.FileExists[@"C:\Project/test.csproj"] = true;
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
@@ -451,7 +446,7 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.LoadXml[@"C:\Project/test.csproj"] = xml;
var autobuilder = CreateAutoBuilder(false);
TestAutobuilderScript(autobuilder, 0, 7);
TestAutobuilderScript(autobuilder, 0, 5);
}
[Fact]
@@ -522,8 +517,6 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
public void TestLinuxBuildlessExtractionSuccess()
{
Actions.RunProcess[@"C:\codeql\csharp/tools/linux64/Semmle.Extraction.CSharp.Standalone --references:."] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
@@ -531,7 +524,7 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.EnumerateDirectories[@"C:\Project"] = "";
var autobuilder = CreateAutoBuilder(false, buildless: "true");
TestAutobuilderScript(autobuilder, 0, 3);
TestAutobuilderScript(autobuilder, 0, 1);
}
[Fact]
@@ -552,8 +545,6 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
public void TestLinuxBuildlessExtractionSolution()
{
Actions.RunProcess[@"C:\codeql\csharp/tools/linux64/Semmle.Extraction.CSharp.Standalone foo.sln --references:."] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
@@ -561,7 +552,7 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.EnumerateDirectories[@"C:\Project"] = "";
var autobuilder = CreateAutoBuilder(false, buildless: "true", solution: "foo.sln");
TestAutobuilderScript(autobuilder, 0, 3);
TestAutobuilderScript(autobuilder, 0, 1);
}
void SkipVsWhere()
@@ -598,8 +589,6 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.RunProcess["dotnet --list-runtimes"] = 1;
Actions.RunProcessOut["dotnet --list-runtimes"] = "";
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto ""./build.sh --skip-tests"""] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
@@ -609,7 +598,7 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
SkipVsWhere();
var autobuilder = CreateAutoBuilder(false, buildCommand: "./build.sh --skip-tests");
TestAutobuilderScript(autobuilder, 0, 4);
TestAutobuilderScript(autobuilder, 0, 2);
}
[Fact]
@@ -624,12 +613,10 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.RunProcessOut["dotnet --list-runtimes"] = "";
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/build/build.sh"] = 0;
Actions.RunProcessWorkingDirectory[@"C:\odasa/tools/odasa index --auto C:\Project/build/build.sh"] = @"C:\Project/build";
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
var autobuilder = CreateAutoBuilder(false);
TestAutobuilderScript(autobuilder, 0, 5);
TestAutobuilderScript(autobuilder, 0, 3);
}
[Fact]
@@ -679,12 +666,10 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto C:\Project\build.bat"] = 0;
Actions.RunProcessWorkingDirectory[@"cmd.exe /C C:\odasa\tools\odasa index --auto C:\Project\build.bat"] = @"C:\Project";
Actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
var autobuilder = CreateAutoBuilder(true);
TestAutobuilderScript(autobuilder, 0, 3);
TestAutobuilderScript(autobuilder, 0, 1);
}
[Fact]
@@ -729,8 +714,6 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test2.sln"] = 0;
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test2.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
@@ -752,7 +735,7 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
autobuilder.ProjectsOrSolutionsToBuild.Add(testSolution1);
autobuilder.ProjectsOrSolutionsToBuild.Add(testSolution2);
TestAutobuilderScript(autobuilder, 0, 6);
TestAutobuilderScript(autobuilder, 0, 4);
}
[Fact]
@@ -762,8 +745,6 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test1.csproj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test2.csproj"] = 0;
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test2.csproj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
Actions.FileExists[@"C:\Project\test1.csproj"] = true;
Actions.FileExists[@"C:\Project\test2.csproj"] = true;
@@ -799,7 +780,7 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
var autobuilder = CreateAutoBuilder(true, msBuildArguments: "/P:Fu=Bar", msBuildTarget: "Windows", msBuildPlatform: "x86", msBuildConfiguration: "Debug",
vsToolsVersion: "12");
TestAutobuilderScript(autobuilder, 0, 6);
TestAutobuilderScript(autobuilder, 0, 4);
}
[Fact]
@@ -834,8 +815,6 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
{
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test2.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
@@ -855,15 +834,13 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
autobuilder.ProjectsOrSolutionsToBuild.Add(testSolution1);
autobuilder.ProjectsOrSolutionsToBuild.Add(testSolution2);
TestAutobuilderScript(autobuilder, 0, 4);
TestAutobuilderScript(autobuilder, 0, 2);
}
[Fact]
public void TestSkipNugetBuildless()
{
Actions.RunProcess[@"C:\codeql\csharp/tools/linux64/Semmle.Extraction.CSharp.Standalone foo.sln --references:. --skip-nuget"] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
@@ -871,7 +848,7 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.EnumerateDirectories[@"C:\Project"] = "";
var autobuilder = CreateAutoBuilder(false, buildless: "true", solution: "foo.sln", nugetRestore: "false");
TestAutobuilderScript(autobuilder, 0, 3);
TestAutobuilderScript(autobuilder, 0, 1);
}
@@ -885,8 +862,6 @@ Microsoft.NETCore.App 2.1.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.RunProcess[@"dotnet clean C:\Project/test.csproj"] = 0;
Actions.RunProcess[@"dotnet restore C:\Project/test.csproj"] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto dotnet build --no-incremental /p:UseSharedCompilation=false --no-restore C:\Project/test.csproj"] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
Actions.FileExists[@"C:\Project/test.csproj"] = true;
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
@@ -904,7 +879,7 @@ Microsoft.NETCore.App 2.1.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.LoadXml[@"C:\Project/test.csproj"] = xml;
var autobuilder = CreateAutoBuilder(false, dotnetArguments: "--no-restore"); // nugetRestore=false does not work for now.
TestAutobuilderScript(autobuilder, 0, 7);
TestAutobuilderScript(autobuilder, 0, 5);
}
[Fact]
@@ -922,8 +897,6 @@ Microsoft.NETCore.App 3.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.RunProcess[@"C:\Project/.dotnet/dotnet clean C:\Project/test.csproj"] = 0;
Actions.RunProcess[@"C:\Project/.dotnet/dotnet restore C:\Project/test.csproj"] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/.dotnet/dotnet build --no-incremental C:\Project/test.csproj"] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
Actions.FileExists["test.csproj"] = true;
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
@@ -943,7 +916,7 @@ Microsoft.NETCore.App 3.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.DownloadFiles.Add(("https://dot.net/v1/dotnet-install.sh", "dotnet-install.sh"));
var autobuilder = CreateAutoBuilder(false, dotnetVersion: "2.1.3");
TestAutobuilderScript(autobuilder, 0, 11);
TestAutobuilderScript(autobuilder, 0, 9);
}
[Fact]
@@ -964,8 +937,6 @@ Microsoft.NETCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.RunProcess[@"C:\Project/.dotnet/dotnet clean C:\Project/test.csproj"] = 0;
Actions.RunProcess[@"C:\Project/.dotnet/dotnet restore C:\Project/test.csproj"] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/.dotnet/dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project/test.csproj"] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
Actions.FileExists["test.csproj"] = true;
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
@@ -985,7 +956,7 @@ Microsoft.NETCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.DownloadFiles.Add(("https://dot.net/v1/dotnet-install.sh", "dotnet-install.sh"));
var autobuilder = CreateAutoBuilder(false, dotnetVersion: "2.1.3");
TestAutobuilderScript(autobuilder, 0, 11);
TestAutobuilderScript(autobuilder, 0, 9);
}
[Fact]
@@ -999,8 +970,6 @@ Microsoft.NETCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet clean C:\Project\test.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet restore C:\Project\test.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto C:\Project\.dotnet\dotnet build --no-incremental C:\Project\test.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
Actions.FileExists[@"C:\Project\test.csproj"] = true;
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
@@ -1019,7 +988,7 @@ Microsoft.NETCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.LoadXml[@"C:\Project\test.csproj"] = xml;
var autobuilder = CreateAutoBuilder(true, dotnetVersion: "2.1.3");
TestAutobuilderScript(autobuilder, 0, 9);
TestAutobuilderScript(autobuilder, 0, 7);
}
[Fact]
@@ -1028,8 +997,6 @@ Microsoft.NETCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\dirs.proj"] = 1;
Actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\dirs.proj"] = 0;
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\dirs.proj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
Actions.FileExists[@"C:\Project\a\test.csproj"] = true;
Actions.FileExists[@"C:\Project\dirs.proj"] = true;
@@ -1065,7 +1032,7 @@ Microsoft.NETCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
var autobuilder = CreateAutoBuilder(true, msBuildArguments: "/P:Fu=Bar", msBuildTarget: "Windows", msBuildPlatform: "x86", msBuildConfiguration: "Debug",
vsToolsVersion: "12", allSolutions: "true");
TestAutobuilderScript(autobuilder, 0, 5);
TestAutobuilderScript(autobuilder, 0, 3);
}
[Fact]
@@ -1074,8 +1041,6 @@ Microsoft.NETCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.RunProcess[@"nuget restore C:\Project/dirs.proj"] = 1;
Actions.RunProcess[@"mono C:\Project/.nuget/nuget.exe restore C:\Project/dirs.proj"] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto msbuild C:\Project/dirs.proj /p:UseSharedCompilation=false /t:rebuild /p:MvcBuildViews=true"] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;
Actions.FileExists["csharp.log"] = true;
Actions.FileExists[@"C:\Project/a/test.csproj"] = true;
Actions.FileExists[@"C:\Project/dirs.proj"] = true;
@@ -1104,7 +1069,7 @@ Microsoft.NETCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.LoadXml[@"C:\Project/dirs.proj"] = dirsproj;
var autobuilder = CreateAutoBuilder(false);
TestAutobuilderScript(autobuilder, 0, 5);
TestAutobuilderScript(autobuilder, 0, 3);
}
[Fact]

View File

@@ -1,23 +0,0 @@
using Semmle.Autobuild.Shared;
namespace Semmle.Autobuild.CSharp
{
/// <summary>
/// ASP extraction.
/// </summary>
class AspBuildRule : IBuildRule
{
public BuildScript Analyse(Autobuilder builder, bool auto)
{
var javaHome = builder.JavaHome;
var dist = builder.Distribution;
var command = new CommandBuilder(builder.Actions).
RunCommand(builder.Actions.PathCombine(javaHome, "bin", "java")).
Argument("-jar").
QuoteArgument(builder.Actions.PathCombine(dist, "tools", "extractor-asp.jar")).
Argument(".");
return command.Script;
}
}
}

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