mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Merge remote-tracking branch 'origin/codeql-cli-2.16.1' into henrymercer/2.16.0-mergeback
This commit is contained in:
12
.github/workflows/mad_modelDiff.yml
vendored
12
.github/workflows/mad_modelDiff.yml
vendored
@@ -12,6 +12,7 @@ on:
|
||||
- main
|
||||
paths:
|
||||
- "java/ql/src/utils/modelgenerator/**/*.*"
|
||||
- "misc/scripts/models-as-data/*.*"
|
||||
- ".github/workflows/mad_modelDiff.yml"
|
||||
|
||||
permissions:
|
||||
@@ -61,8 +62,9 @@ jobs:
|
||||
DATABASE=$2
|
||||
cd codeql-$QL_VARIANT
|
||||
SHORTNAME=`basename $DATABASE`
|
||||
python java/ql/src/utils/modelgenerator/GenerateFlowModel.py --with-summaries --with-sinks $DATABASE ${SHORTNAME}.temp.model.yml
|
||||
mv java/ql/lib/ext/generated/${SHORTNAME}.temp.model.yml $MODELS/${SHORTNAME}Generated_${QL_VARIANT}.model.yml
|
||||
python java/ql/src/utils/modelgenerator/GenerateFlowModel.py --with-summaries --with-sinks $DATABASE $SHORTNAME/$QL_VARIANT
|
||||
mkdir -p $MODELS/$SHORTNAME
|
||||
mv java/ql/lib/ext/generated/$SHORTNAME/$QL_VARIANT $MODELS/$SHORTNAME
|
||||
cd ..
|
||||
}
|
||||
|
||||
@@ -85,16 +87,16 @@ jobs:
|
||||
set -x
|
||||
MODELS=`pwd`/tmp-models
|
||||
ls -1 tmp-models/
|
||||
for m in $MODELS/*_main.model.yml ; do
|
||||
for m in $MODELS/*/main/*.model.yml ; do
|
||||
t="${m/main/"pr"}"
|
||||
basename=`basename $m`
|
||||
name="diff_${basename/_main.model.yml/""}"
|
||||
name="diff_${basename/.model.yml/""}"
|
||||
(diff -w -u $m $t | diff2html -i stdin -F $MODELS/$name.html) || true
|
||||
done
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: models
|
||||
path: tmp-models/*.model.yml
|
||||
path: tmp-models/**/**/*.model.yml
|
||||
retention-days: 20
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
|
||||
@@ -473,10 +473,6 @@
|
||||
"ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModelsExtensions.qll",
|
||||
"python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModelsExtensions.qll"
|
||||
],
|
||||
"Typo database": [
|
||||
"javascript/ql/src/Expressions/TypoDatabase.qll",
|
||||
"ql/ql/src/codeql_ql/style/TypoDatabase.qll"
|
||||
],
|
||||
"Swift declarations test file": [
|
||||
"swift/ql/test/extractor-tests/declarations/declarations.swift",
|
||||
"swift/ql/test/library-tests/ast/declarations.swift"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
description: Support C++17 if and switch initializers
|
||||
compatibility: partial
|
||||
constexpr_if_initialization.rel: delete
|
||||
if_initialization.rel: delete
|
||||
switch_initialization.rel: delete
|
||||
exprparents.rel: run exprparents.qlo
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
## 0.12.4
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Deleted many deprecated predicates and classes with uppercase `XML`, `SSA`, `SAL`, `SQL`, etc. in their names. Use the PascalCased versions instead.
|
||||
* Deleted the deprecated `StrcatFunction` class, use `semmle.code.cpp.models.implementations.Strcat.qll` instead.
|
||||
|
||||
## 0.12.3
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
6
cpp/ql/lib/change-notes/released/0.12.4.md
Normal file
6
cpp/ql/lib/change-notes/released/0.12.4.md
Normal file
@@ -0,0 +1,6 @@
|
||||
## 0.12.4
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Deleted many deprecated predicates and classes with uppercase `XML`, `SSA`, `SAL`, `SQL`, etc. in their names. Use the PascalCased versions instead.
|
||||
* Deleted the deprecated `StrcatFunction` class, use `semmle.code.cpp.models.implementations.Strcat.qll` instead.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.12.3
|
||||
lastReleaseVersion: 0.12.4
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 0.12.3
|
||||
version: 0.12.4
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -380,9 +380,6 @@ class Class extends UserType {
|
||||
*/
|
||||
predicate isPod() { is_pod_class(underlyingElement(this)) }
|
||||
|
||||
/** DEPRECATED: Alias for isPod */
|
||||
deprecated predicate isPOD() { this.isPod() }
|
||||
|
||||
/**
|
||||
* Holds if this class, struct or union is a standard-layout class
|
||||
* [N4140 9(7)]. Also holds for structs in C programs.
|
||||
|
||||
@@ -104,9 +104,6 @@ predicate isPodClass03(Class c) {
|
||||
)
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for isPodClass03 */
|
||||
deprecated predicate isPODClass03 = isPodClass03/1;
|
||||
|
||||
/**
|
||||
* Holds if `t` is a POD type, according to the rules specified in
|
||||
* C++03 3.9(10):
|
||||
@@ -126,6 +123,3 @@ predicate isPodType03(Type t) {
|
||||
isPodType03(ut.(SpecifiedType).getUnspecifiedType())
|
||||
)
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for isPodType03 */
|
||||
deprecated predicate isPODType03 = isPodType03/1;
|
||||
|
||||
@@ -32,9 +32,6 @@ class XmlLocatable extends @xmllocatable, TXmlLocatable {
|
||||
string toString() { none() } // overridden in subclasses
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlLocatable */
|
||||
deprecated class XMLLocatable = XmlLocatable;
|
||||
|
||||
/**
|
||||
* An `XmlParent` is either an `XmlElement` or an `XmlFile`,
|
||||
* both of which can contain other elements.
|
||||
@@ -95,9 +92,6 @@ class XmlParent extends @xmlparent {
|
||||
string toString() { result = this.getName() }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlParent */
|
||||
deprecated class XMLParent = XmlParent;
|
||||
|
||||
/** An XML file. */
|
||||
class XmlFile extends XmlParent, File {
|
||||
XmlFile() { xmlEncoding(this, _) }
|
||||
@@ -119,14 +113,8 @@ class XmlFile extends XmlParent, File {
|
||||
|
||||
/** Gets a DTD associated with this XML file. */
|
||||
XmlDtd getADtd() { xmlDTDs(result, _, _, _, this) }
|
||||
|
||||
/** DEPRECATED: Alias for getADtd */
|
||||
deprecated XmlDtd getADTD() { result = this.getADtd() }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlFile */
|
||||
deprecated class XMLFile = XmlFile;
|
||||
|
||||
/**
|
||||
* An XML document type definition (DTD).
|
||||
*
|
||||
@@ -163,9 +151,6 @@ class XmlDtd extends XmlLocatable, @xmldtd {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlDtd */
|
||||
deprecated class XMLDTD = XmlDtd;
|
||||
|
||||
/**
|
||||
* An XML element in an XML file.
|
||||
*
|
||||
@@ -221,9 +206,6 @@ class XmlElement extends @xmlelement, XmlParent, XmlLocatable {
|
||||
override string toString() { result = this.getName() }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlElement */
|
||||
deprecated class XMLElement = XmlElement;
|
||||
|
||||
/**
|
||||
* An attribute that occurs inside an XML element.
|
||||
*
|
||||
@@ -254,9 +236,6 @@ class XmlAttribute extends @xmlattribute, XmlLocatable {
|
||||
override string toString() { result = this.getName() + "=" + this.getValue() }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlAttribute */
|
||||
deprecated class XMLAttribute = XmlAttribute;
|
||||
|
||||
/**
|
||||
* A namespace used in an XML file.
|
||||
*
|
||||
@@ -273,9 +252,6 @@ class XmlNamespace extends XmlLocatable, @xmlnamespace {
|
||||
/** Gets the URI of this namespace. */
|
||||
string getUri() { xmlNs(this, _, result, _) }
|
||||
|
||||
/** DEPRECATED: Alias for getUri */
|
||||
deprecated string getURI() { result = this.getUri() }
|
||||
|
||||
/** Holds if this namespace has no prefix. */
|
||||
predicate isDefault() { this.getPrefix() = "" }
|
||||
|
||||
@@ -286,9 +262,6 @@ class XmlNamespace extends XmlLocatable, @xmlnamespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlNamespace */
|
||||
deprecated class XMLNamespace = XmlNamespace;
|
||||
|
||||
/**
|
||||
* A comment in an XML file.
|
||||
*
|
||||
@@ -309,9 +282,6 @@ class XmlComment extends @xmlcomment, XmlLocatable {
|
||||
override string toString() { result = this.getText() }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlComment */
|
||||
deprecated class XMLComment = XmlComment;
|
||||
|
||||
/**
|
||||
* A sequence of characters that occurs between opening and
|
||||
* closing tags of an XML element, excluding other elements.
|
||||
@@ -335,6 +305,3 @@ class XmlCharacters extends @xmlcharacters, XmlLocatable {
|
||||
/** Gets a printable representation of this XML character sequence. */
|
||||
override string toString() { result = this.getCharacters() }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlCharacters */
|
||||
deprecated class XMLCharacters = XmlCharacters;
|
||||
|
||||
@@ -5,9 +5,6 @@ class NullMacro extends Macro {
|
||||
NullMacro() { this.getHead() = "NULL" }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for NullMacro */
|
||||
deprecated class NULLMacro = NullMacro;
|
||||
|
||||
/** A use of the NULL macro. */
|
||||
class NULL extends Literal {
|
||||
NULL() { exists(NullMacro nm | this = nm.getAnInvocation().getAnExpandedElement()) }
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import cpp
|
||||
|
||||
/**
|
||||
* DEPRECATED: use `semmle.code.cpp.models.implementations.Strcat.qll` instead.
|
||||
*
|
||||
* A function that concatenates the string from its second argument
|
||||
* to the string from its first argument, for example `strcat`.
|
||||
*/
|
||||
deprecated class StrcatFunction extends Function {
|
||||
StrcatFunction() {
|
||||
this.getName() =
|
||||
[
|
||||
"strcat", // strcat(dst, src)
|
||||
"strncat", // strncat(dst, src, max_amount)
|
||||
"wcscat", // wcscat(dst, src)
|
||||
"_mbscat", // _mbscat(dst, src)
|
||||
"wcsncat", // wcsncat(dst, src, max_amount)
|
||||
"_mbsncat", // _mbsncat(dst, src, max_amount)
|
||||
"_mbsncat_l" // _mbsncat_l(dst, src, max_amount, locale)
|
||||
]
|
||||
}
|
||||
}
|
||||
101
cpp/ql/lib/semmle/code/cpp/commons/StringConcatenation.qll
Normal file
101
cpp/ql/lib/semmle/code/cpp/commons/StringConcatenation.qll
Normal file
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* A library for detecting general string concatenations.
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.models.implementations.Strcat
|
||||
import semmle.code.cpp.models.interfaces.FormattingFunction
|
||||
private import semmle.code.cpp.dataflow.new.DataFlow
|
||||
|
||||
/**
|
||||
* A call that performs a string concatenation. A string can be either a C
|
||||
* string (i.e., a value of type `char*`), or a C++ string (i.e., a value of
|
||||
* type `std::string`).
|
||||
*/
|
||||
class StringConcatenation extends Call {
|
||||
StringConcatenation() {
|
||||
// sprintf-like functions, i.e., concat through formatting
|
||||
this instanceof FormattingFunctionCall
|
||||
or
|
||||
this.getTarget() instanceof StrcatFunction
|
||||
or
|
||||
this.getTarget() instanceof StrlcatFunction
|
||||
or
|
||||
// operator+ and ostream (<<) concat
|
||||
exists(Call call, Operator op |
|
||||
call.getTarget() = op and
|
||||
op.hasQualifiedName(["std", "bsl"], ["operator+", "operator<<"]) and
|
||||
op.getType()
|
||||
.stripType()
|
||||
.(UserType)
|
||||
.hasQualifiedName(["std", "bsl"], ["basic_string", "basic_ostream"]) and
|
||||
this = call
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an operand of this concatenation (one of the string operands being
|
||||
* concatenated).
|
||||
* Will not return out param for sprintf-like functions, but will consider the format string
|
||||
* to be part of the operands.
|
||||
*/
|
||||
Expr getAnOperand() {
|
||||
// The result is an argument of 'this' (a call)
|
||||
result = this.getAnArgument() and
|
||||
// addresses odd behavior with overloaded operators
|
||||
// i.e., "call to operator+" appearing as an operand
|
||||
// occurs in cases like `string s = s1 + s2 + s3`, which is represented as
|
||||
// `string s = (s1.operator+(s2)).operator+(s3);`
|
||||
// By limiting to non-calls we get the leaf operands (the variables or raw strings)
|
||||
// also, by not enumerating allowed types (variables and strings) we avoid issues
|
||||
// with missed corner cases or extensions/changes to CodeQL in the future which might
|
||||
// invalidate that approach.
|
||||
not result instanceof Call and
|
||||
// Limit the result type to string
|
||||
(
|
||||
result.getUnderlyingType().stripType().getName() = "char"
|
||||
or
|
||||
result
|
||||
.getType()
|
||||
.getUnspecifiedType()
|
||||
.(UserType)
|
||||
.hasQualifiedName(["std", "bsl"], "basic_string")
|
||||
) and
|
||||
// when 'this' is a `FormattingFunctionCall` the result must be the format string argument
|
||||
// or one of the formatting arguments
|
||||
(
|
||||
this instanceof FormattingFunctionCall
|
||||
implies
|
||||
(
|
||||
result = this.(FormattingFunctionCall).getFormat()
|
||||
or
|
||||
exists(int n |
|
||||
result = this.getArgument(n) and
|
||||
n >= this.(FormattingFunctionCall).getTarget().getFirstFormatArgumentIndex()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data flow node representing the concatenation result.
|
||||
*/
|
||||
DataFlow::Node getResultNode() {
|
||||
if this.getTarget() instanceof StrcatFunction
|
||||
then
|
||||
result.asDefiningArgument() =
|
||||
this.getArgument(this.getTarget().(StrcatFunction).getParamDest())
|
||||
or
|
||||
// Hardcoding it is also the return
|
||||
result.asExpr() = this.(Call)
|
||||
else
|
||||
if this.getTarget() instanceof StrlcatFunction
|
||||
then (
|
||||
result.asDefiningArgument() =
|
||||
this.getArgument(this.getTarget().(StrlcatFunction).getParamDest())
|
||||
) else
|
||||
if this instanceof FormattingFunctionCall
|
||||
then result.asDefiningArgument() = this.(FormattingFunctionCall).getOutputArgument(_)
|
||||
else result.asExpr() = this.(Call)
|
||||
}
|
||||
}
|
||||
@@ -54,18 +54,6 @@ private predicate functionSignature(Function f, string qualifiedName, int nparam
|
||||
not f.isStatic()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the set of viable implementations that can be called by `call`
|
||||
* might be improved by knowing the call context.
|
||||
*/
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call, Function f) { none() }
|
||||
|
||||
/**
|
||||
* Gets a viable dispatch target of `call` in the context `ctx`. This is
|
||||
* restricted to those `call`s for which a context might make a difference.
|
||||
*/
|
||||
Function viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) { none() }
|
||||
|
||||
/** A parameter position represented by an integer. */
|
||||
class ParameterPosition extends int {
|
||||
ParameterPosition() { any(ParameterNode p).isParameterOf(_, this) }
|
||||
|
||||
@@ -249,9 +249,7 @@ private predicate functionSignature(Function f, string qualifiedName, int nparam
|
||||
* Holds if the set of viable implementations that can be called by `call`
|
||||
* might be improved by knowing the call context.
|
||||
*/
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable f) {
|
||||
mayBenefitFromCallContext(call, f, _)
|
||||
}
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call) { mayBenefitFromCallContext(call, _, _) }
|
||||
|
||||
/**
|
||||
* Holds if `call` is a call through a function pointer, and the pointer
|
||||
|
||||
@@ -22,4 +22,8 @@ module CppDataFlow implements InputSig {
|
||||
predicate getAdditionalFlowIntoCallNodeTerm = Private::getAdditionalFlowIntoCallNodeTerm/2;
|
||||
|
||||
predicate validParameterAliasStep = Private::validParameterAliasStep/2;
|
||||
|
||||
predicate mayBenefitFromCallContext = Private::mayBenefitFromCallContext/1;
|
||||
|
||||
predicate viableImplInCallContext = Private::viableImplInCallContext/2;
|
||||
}
|
||||
|
||||
@@ -1394,11 +1394,21 @@ abstract private class ExprNodeBase extends Node {
|
||||
final Expr getExpr(int n) { result = this.getConvertedExpr(n).getUnconverted() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there exists a dataflow node whose `asExpr(n)` should evaluate
|
||||
* to `e`.
|
||||
*/
|
||||
private predicate exprNodeShouldBe(Expr e, int n) {
|
||||
exprNodeShouldBeInstruction(_, e, n) or
|
||||
exprNodeShouldBeOperand(_, e, n) or
|
||||
exprNodeShouldBeIndirectOutNode(_, e, n)
|
||||
}
|
||||
|
||||
private class InstructionExprNode extends ExprNodeBase, InstructionNode {
|
||||
InstructionExprNode() {
|
||||
exists(Expr e, int n |
|
||||
exprNodeShouldBeInstruction(this, e, n) and
|
||||
not exprNodeShouldBeInstruction(_, e, n + 1)
|
||||
not exprNodeShouldBe(e, n + 1)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1409,7 +1419,7 @@ private class OperandExprNode extends ExprNodeBase, OperandNode {
|
||||
OperandExprNode() {
|
||||
exists(Expr e, int n |
|
||||
exprNodeShouldBeOperand(this, e, n) and
|
||||
not exprNodeShouldBeOperand(_, e, n + 1)
|
||||
not exprNodeShouldBe(e, n + 1)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -149,11 +149,16 @@ private newtype TDefOrUseImpl =
|
||||
private predicate isGlobalUse(
|
||||
GlobalLikeVariable v, IRFunction f, int indirection, int indirectionIndex
|
||||
) {
|
||||
exists(VariableAddressInstruction vai |
|
||||
vai.getEnclosingIRFunction() = f and
|
||||
vai.getAstVariable() = v and
|
||||
isDef(_, _, _, vai, indirection, indirectionIndex)
|
||||
)
|
||||
// Generate a "global use" at the end of the function body if there's a
|
||||
// direct definition somewhere in the body of the function
|
||||
indirection =
|
||||
min(int cand, VariableAddressInstruction vai |
|
||||
vai.getEnclosingIRFunction() = f and
|
||||
vai.getAstVariable() = v and
|
||||
isDef(_, _, _, vai, cand, indirectionIndex)
|
||||
|
|
||||
cand
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isGlobalDefImpl(
|
||||
@@ -447,6 +452,57 @@ class FinalParameterUse extends UseImpl, TFinalParameterUse {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A use that models a synthetic "last use" of a global variable just before a
|
||||
* function returns.
|
||||
*
|
||||
* We model global variable flow by:
|
||||
* - Inserting a last use of any global variable that's modified by a function
|
||||
* - Flowing from the last use to the `VariableNode` that represents the global
|
||||
* variable.
|
||||
* - Flowing from the `VariableNode` to an "initial def" of the global variable
|
||||
* in any function that may read the global variable.
|
||||
* - Flowing from the initial definition to any subsequent uses of the global
|
||||
* variable in the function body.
|
||||
*
|
||||
* For example, consider the following pair of functions:
|
||||
* ```cpp
|
||||
* int global;
|
||||
* int source();
|
||||
* void sink(int);
|
||||
*
|
||||
* void set_global() {
|
||||
* global = source();
|
||||
* }
|
||||
*
|
||||
* void read_global() {
|
||||
* sink(global);
|
||||
* }
|
||||
* ```
|
||||
* we insert global uses and defs so that (from the point-of-view of dataflow)
|
||||
* the above scenario looks like:
|
||||
* ```cpp
|
||||
* int global; // (1)
|
||||
* int source();
|
||||
* void sink(int);
|
||||
*
|
||||
* void set_global() {
|
||||
* global = source();
|
||||
* __global_use(global); // (2)
|
||||
* }
|
||||
*
|
||||
* void read_global() {
|
||||
* global = __global_def; // (3)
|
||||
* sink(global); // (4)
|
||||
* }
|
||||
* ```
|
||||
* and flow from `source()` to the argument of `sink` is then modeled as
|
||||
* follows:
|
||||
* 1. Flow from `source()` to `(2)` (via SSA).
|
||||
* 2. Flow from `(2)` to `(1)` (via a `jumpStep`).
|
||||
* 3. Flow from `(1)` to `(3)` (via a `jumpStep`).
|
||||
* 4. Flow from `(3)` to `(4)` (via SSA).
|
||||
*/
|
||||
class GlobalUse extends UseImpl, TGlobalUse {
|
||||
GlobalLikeVariable global;
|
||||
IRFunction f;
|
||||
@@ -494,6 +550,12 @@ class GlobalUse extends UseImpl, TGlobalUse {
|
||||
override BaseSourceVariableInstruction getBase() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A definition that models a synthetic "initial definition" of a global
|
||||
* variable just after the function entry point.
|
||||
*
|
||||
* See the QLDoc for `GlobalUse` for how this is used.
|
||||
*/
|
||||
class GlobalDefImpl extends DefOrUseImpl, TGlobalDefImpl {
|
||||
GlobalLikeVariable global;
|
||||
IRFunction f;
|
||||
@@ -547,7 +609,10 @@ class GlobalDefImpl extends DefOrUseImpl, TGlobalDefImpl {
|
||||
*/
|
||||
predicate adjacentDefRead(DefOrUse defOrUse1, UseOrPhi use) {
|
||||
exists(IRBlock bb1, int i1, SourceVariable v |
|
||||
defOrUse1.asDefOrUse().hasIndexInBlock(bb1, i1, v)
|
||||
defOrUse1
|
||||
.asDefOrUse()
|
||||
.hasIndexInBlock(pragma[only_bind_out](bb1), pragma[only_bind_out](i1),
|
||||
pragma[only_bind_out](v))
|
||||
|
|
||||
exists(IRBlock bb2, int i2, DefinitionExt def |
|
||||
adjacentDefReadExt(pragma[only_bind_into](def), pragma[only_bind_into](bb1),
|
||||
@@ -569,7 +634,11 @@ predicate adjacentDefRead(DefOrUse defOrUse1, UseOrPhi use) {
|
||||
* flows to `useOrPhi`.
|
||||
*/
|
||||
private predicate globalDefToUse(GlobalDef globalDef, UseOrPhi useOrPhi) {
|
||||
exists(IRBlock bb1, int i1, SourceVariable v | globalDef.hasIndexInBlock(bb1, i1, v) |
|
||||
exists(IRBlock bb1, int i1, SourceVariable v |
|
||||
globalDef
|
||||
.hasIndexInBlock(pragma[only_bind_out](bb1), pragma[only_bind_out](i1),
|
||||
pragma[only_bind_out](v))
|
||||
|
|
||||
exists(IRBlock bb2, int i2 |
|
||||
adjacentDefReadExt(_, pragma[only_bind_into](bb1), pragma[only_bind_into](i1),
|
||||
pragma[only_bind_into](bb2), pragma[only_bind_into](i2)) and
|
||||
|
||||
@@ -1068,6 +1068,3 @@ module Ssa {
|
||||
|
||||
predicate hasUnreachedInstruction = Cached::hasUnreachedInstructionCached/1;
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for Ssa */
|
||||
deprecated module SSA = Ssa;
|
||||
|
||||
@@ -3,13 +3,6 @@ import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.reachability.Rea
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.reachability.Dominance as Dominance
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.IR as NewIR
|
||||
import semmle.code.cpp.ir.implementation.internal.TInstruction::AliasedSsaInstructions as SsaInstructions
|
||||
|
||||
/** DEPRECATED: Alias for SsaInstructions */
|
||||
deprecated module SSAInstructions = SsaInstructions;
|
||||
|
||||
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
||||
import AliasedSSA as Alias
|
||||
import semmle.code.cpp.ir.implementation.internal.TOperand::AliasedSsaOperands as SsaOperands
|
||||
|
||||
/** DEPRECATED: Alias for SsaOperands */
|
||||
deprecated module SSAOperands = SsaOperands;
|
||||
|
||||
@@ -2,6 +2,3 @@ import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
||||
import semmle.code.cpp.ir.implementation.raw.internal.IRConstruction as IRConstruction
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSAConstruction as UnaliasedSsa
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.internal.SSAConstruction as AliasedSsa
|
||||
|
||||
/** DEPRECATED: Alias for AliasedSsa */
|
||||
deprecated module AliasedSSA = AliasedSsa;
|
||||
|
||||
@@ -1068,6 +1068,3 @@ module Ssa {
|
||||
|
||||
predicate hasUnreachedInstruction = Cached::hasUnreachedInstructionCached/1;
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for Ssa */
|
||||
deprecated module SSA = Ssa;
|
||||
|
||||
@@ -4,13 +4,6 @@ import semmle.code.cpp.ir.implementation.raw.internal.reachability.Dominance as
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.IR as NewIR
|
||||
import semmle.code.cpp.ir.implementation.raw.internal.IRConstruction as RawStage
|
||||
import semmle.code.cpp.ir.implementation.internal.TInstruction::UnaliasedSsaInstructions as SsaInstructions
|
||||
|
||||
/** DEPRECATED: Alias for SsaInstructions */
|
||||
deprecated module SSAInstructions = SsaInstructions;
|
||||
|
||||
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
||||
import SimpleSSA as Alias
|
||||
import semmle.code.cpp.ir.implementation.internal.TOperand::UnaliasedSsaOperands as SsaOperands
|
||||
|
||||
/** DEPRECATED: Alias for SsaOperands */
|
||||
deprecated module SSAOperands = SsaOperands;
|
||||
|
||||
@@ -27,10 +27,12 @@ private class StandardDeallocationFunction extends DeallocationFunction {
|
||||
or
|
||||
this.hasGlobalOrStdName([
|
||||
// --- Windows Memory Management for Windows Drivers
|
||||
"ExFreePoolWithTag", "ExDeleteTimer", "IoFreeMdl", "IoFreeWorkItem", "IoFreeErrorLogEntry",
|
||||
"MmFreeContiguousMemory", "MmFreeContiguousMemorySpecifyCache", "MmFreeNonCachedMemory",
|
||||
"MmFreeMappingAddress", "MmFreePagesFromMdl", "MmUnmapReservedMapping",
|
||||
"MmUnmapLockedPages",
|
||||
"ExFreePool", "ExFreePoolWithTag", "ExDeleteTimer", "IoFreeIrp", "IoFreeMdl",
|
||||
"IoFreeErrorLogEntry", "IoFreeWorkItem", "MmFreeContiguousMemory",
|
||||
"MmFreeContiguousMemorySpecifyCache", "MmFreeNonCachedMemory", "MmFreeMappingAddress",
|
||||
"MmFreePagesFromMdl", "MmUnmapReservedMapping", "MmUnmapLockedPages",
|
||||
"NdisFreeGenericObject", "NdisFreeMemory", "NdisFreeMemoryWithTag", "NdisFreeMdl",
|
||||
"NdisFreeNetBufferListPool", "NdisFreeNetBufferPool",
|
||||
// --- Windows Global / Local legacy allocation
|
||||
"LocalFree", "GlobalFree", "LocalReAlloc", "GlobalReAlloc",
|
||||
// --- Windows System Services allocation
|
||||
@@ -47,6 +49,7 @@ private class StandardDeallocationFunction extends DeallocationFunction {
|
||||
this.hasGlobalOrStdName([
|
||||
// --- Windows Memory Management for Windows Drivers
|
||||
"ExFreeToLookasideListEx", "ExFreeToPagedLookasideList", "ExFreeToNPagedLookasideList",
|
||||
"NdisFreeMemoryWithTagPriority", "StorPortFreeMdl", "StorPortFreePool",
|
||||
// --- NetBSD pool manager
|
||||
"pool_put", "pool_cache_put"
|
||||
]) and
|
||||
|
||||
@@ -355,13 +355,13 @@ private predicate linearAccessImpl(Expr expr, VariableAccess v, float p, float q
|
||||
* `cmpWithLinearBound(guard, v, Greater(), true)` and
|
||||
* `cmpWithLinearBound(guard, v, Lesser(), false)` hold.
|
||||
* If `guard` is `4 - v > 5` then
|
||||
* `cmpWithLinearBound(guard, v, Lesser(), false)` and
|
||||
* `cmpWithLinearBound(guard, v, Greater(), true)` hold.
|
||||
* `cmpWithLinearBound(guard, v, Lesser(), true)` and
|
||||
* `cmpWithLinearBound(guard, v, Greater(), false)` hold.
|
||||
*
|
||||
* A more sophisticated predicate, such as `boundFromGuard`, is needed
|
||||
* to compute an actual bound for `v`. This predicate can be used if
|
||||
* you just want to check whether a variable is bounded, or to restrict
|
||||
* a more expensive analysis to just guards that bound a variable.
|
||||
* If an actual bound for `v` is needed, use `upperBound` or `lowerBound`.
|
||||
* This predicate can be used if you just want to check whether a variable
|
||||
* is bounded, or to restrict a more expensive analysis to just guards that
|
||||
* bound a variable.
|
||||
*/
|
||||
predicate cmpWithLinearBound(
|
||||
ComparisonOperation guard, VariableAccess v,
|
||||
|
||||
@@ -1,21 +1,11 @@
|
||||
/**
|
||||
* General library for finding flow from a pointer being freed to a user-specified sink
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.dataflow.new.DataFlow
|
||||
private import semmle.code.cpp.ir.IR
|
||||
|
||||
/**
|
||||
* Signature for a predicate that holds if `n.asExpr() = e` and `n` is a sink in
|
||||
* the `FlowFromFreeConfig` module.
|
||||
*/
|
||||
private signature predicate isSinkSig(DataFlow::Node n, Expr e);
|
||||
|
||||
/**
|
||||
* Holds if `dealloc` is a deallocation expression and `e` is an expression such
|
||||
* that `isFree(_, e)` holds for some `isFree` predicate satisfying `isSinkSig`,
|
||||
* and this source-sink pair should be excluded from the analysis.
|
||||
*/
|
||||
bindingset[dealloc, e]
|
||||
private signature predicate isExcludedSig(DeallocationExpr dealloc, Expr e);
|
||||
|
||||
/**
|
||||
* Holds if `(b1, i1)` strictly post-dominates `(b2, i2)`
|
||||
*/
|
||||
@@ -38,6 +28,31 @@ predicate strictlyDominates(IRBlock b1, int i1, IRBlock b2, int i2) {
|
||||
b1.strictlyDominates(b2)
|
||||
}
|
||||
|
||||
/**
|
||||
* The signature for a module that is used to specify the inputs to the `FlowFromFree` module.
|
||||
*/
|
||||
signature module FlowFromFreeParamSig {
|
||||
/**
|
||||
* Holds if `n.asExpr() = e` and `n` is a sink in the `FlowFromFreeConfig`
|
||||
* module.
|
||||
*/
|
||||
predicate isSink(DataFlow::Node n, Expr e);
|
||||
|
||||
/**
|
||||
* Holds if `dealloc` is a deallocation expression and `e` is an expression such
|
||||
* that `isFree(_, e)` holds for some `isFree` predicate satisfying `isSinkSig`,
|
||||
* and this source-sink pair should be excluded from the analysis.
|
||||
*/
|
||||
bindingset[dealloc, e]
|
||||
predicate isExcluded(DeallocationExpr dealloc, Expr e);
|
||||
|
||||
/**
|
||||
* Holds if `sink` should be considered a `sink` when the source of flow is `source`.
|
||||
*/
|
||||
bindingset[source, sink]
|
||||
default predicate sourceSinkIsRelated(DataFlow::Node source, DataFlow::Node sink) { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a `FlowFromFreeConfig` module that can be used to find flow between
|
||||
* a pointer being freed by some deallocation function, and a user-specified sink.
|
||||
@@ -47,8 +62,8 @@ predicate strictlyDominates(IRBlock b1, int i1, IRBlock b2, int i2) {
|
||||
* 1. The source dominates the sink, or
|
||||
* 2. The sink post-dominates the source.
|
||||
*/
|
||||
module FlowFromFree<isSinkSig/2 isASink, isExcludedSig/2 isExcluded> {
|
||||
module FlowFromFreeConfig implements DataFlow::StateConfigSig {
|
||||
module FlowFromFree<FlowFromFreeParamSig P> {
|
||||
private module FlowFromFreeConfig implements DataFlow::StateConfigSig {
|
||||
class FlowState instanceof Expr {
|
||||
FlowState() { isFree(_, _, this, _) }
|
||||
|
||||
@@ -59,20 +74,12 @@ module FlowFromFree<isSinkSig/2 isASink, isExcludedSig/2 isExcluded> {
|
||||
|
||||
pragma[inline]
|
||||
predicate isSink(DataFlow::Node sink, FlowState state) {
|
||||
exists(
|
||||
Expr e, DataFlow::Node source, IRBlock b1, int i1, IRBlock b2, int i2,
|
||||
DeallocationExpr dealloc
|
||||
|
|
||||
isASink(sink, e) and
|
||||
exists(Expr e, DataFlow::Node source, DeallocationExpr dealloc |
|
||||
P::isSink(sink, e) and
|
||||
isFree(source, _, state, dealloc) and
|
||||
e != state and
|
||||
source.hasIndexInBlock(b1, i1) and
|
||||
sink.hasIndexInBlock(b2, i2) and
|
||||
not isExcluded(dealloc, e)
|
||||
|
|
||||
strictlyDominates(b1, i1, b2, i2)
|
||||
or
|
||||
strictlyPostDominates(b2, i2, b1, i1)
|
||||
not P::isExcluded(dealloc, e) and
|
||||
P::sourceSinkIsRelated(source, sink)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -127,3 +134,38 @@ predicate isExFreePoolCall(FunctionCall fc, Expr e) {
|
||||
fc.getTarget().hasGlobalName("ExFreePool")
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if either `source` strictly dominates `sink`, or `sink` strictly
|
||||
* post-dominates `source`.
|
||||
*/
|
||||
bindingset[source, sink]
|
||||
predicate defaultSourceSinkIsRelated(DataFlow::Node source, DataFlow::Node sink) {
|
||||
exists(IRBlock b1, int i1, IRBlock b2, int i2 |
|
||||
source.hasIndexInBlock(b1, i1) and
|
||||
sink.hasIndexInBlock(b2, i2)
|
||||
|
|
||||
strictlyDominates(b1, i1, b2, i2)
|
||||
or
|
||||
strictlyPostDominates(b2, i2, b1, i1)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* `dealloc1` is a deallocation expression, `e` is an expression that dereferences a
|
||||
* pointer, and the `(dealloc1, e)` pair should be excluded by the `FlowFromFree` library.
|
||||
*
|
||||
* Note that `e` is not necessarily the expression deallocated by `dealloc1`. It will
|
||||
* be bound to the second deallocation as identified by the `FlowFromFree` library.
|
||||
*
|
||||
* From https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-mmfreepagesfrommdl:
|
||||
* "After calling MmFreePagesFromMdl, the caller must also call ExFreePool
|
||||
* to release the memory that was allocated for the MDL structure."
|
||||
*/
|
||||
bindingset[dealloc1, e]
|
||||
predicate isExcludedMmFreePageFromMdl(DeallocationExpr dealloc1, Expr e) {
|
||||
exists(DeallocationExpr dealloc2 | isFree(_, _, e, dealloc2) |
|
||||
dealloc1.(FunctionCall).getTarget().hasGlobalName("MmFreePagesFromMdl") and
|
||||
isExFreePoolCall(dealloc2, _)
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
* General library for tracing Use After Free vulnerabilities.
|
||||
*/
|
||||
|
||||
import cpp
|
||||
private import semmle.code.cpp.security.flowafterfree.FlowAfterFree
|
||||
private import semmle.code.cpp.ir.IR
|
||||
|
||||
/**
|
||||
* Holds if `call` is a call to a function that obviously
|
||||
* doesn't dereference its `i`'th argument.
|
||||
*/
|
||||
private predicate externalCallNeverDereferences(FormattingFunctionCall call, int arg) {
|
||||
exists(int formatArg |
|
||||
pragma[only_bind_out](call.getFormatArgument(formatArg)) =
|
||||
pragma[only_bind_out](call.getArgument(arg)) and
|
||||
call.getFormat().(FormatLiteral).getConvSpec(formatArg) != "%s"
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `e` is a use. A use is a pointer dereference or a
|
||||
* parameter to a call with no function definition.
|
||||
* Uses in deallocation expressions (e.g., free) are excluded.
|
||||
* Default isUse definition for an expression.
|
||||
*/
|
||||
predicate isUse0(Expr e) {
|
||||
not isFree(_, _, e, _) and
|
||||
(
|
||||
// TODO: use DirectDefereferencedByOperation in Dereferenced.qll
|
||||
e = any(PointerDereferenceExpr pde).getOperand()
|
||||
or
|
||||
e = any(PointerFieldAccess pfa).getQualifier()
|
||||
or
|
||||
e = any(ArrayExpr ae).getArrayBase()
|
||||
or
|
||||
e = any(Call call).getQualifier()
|
||||
or
|
||||
// Assume any function without a body will dereference the pointer
|
||||
exists(int i, Call call, Function f |
|
||||
e = call.getArgument(i) and
|
||||
f = call.getTarget() and
|
||||
not f.hasEntryPoint() and
|
||||
// Exclude known functions we know won't dereference the pointer.
|
||||
// For example, a call such as `printf("%p", myPointer)`.
|
||||
not externalCallNeverDereferences(call, i)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private module ParameterSinks {
|
||||
import semmle.code.cpp.ir.ValueNumbering
|
||||
|
||||
private predicate flowsToUse(DataFlow::Node n) {
|
||||
isUse0(n.asExpr())
|
||||
or
|
||||
exists(DataFlow::Node succ |
|
||||
flowsToUse(succ) and
|
||||
DataFlow::localFlowStep(n, succ)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate flowsFromParam(DataFlow::Node n) {
|
||||
flowsToUse(n) and
|
||||
(
|
||||
n.asParameter().getUnspecifiedType() instanceof PointerType
|
||||
or
|
||||
exists(DataFlow::Node prev |
|
||||
flowsFromParam(prev) and
|
||||
DataFlow::localFlowStep(prev, n)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate step(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
flowsFromParam(n1) and
|
||||
flowsFromParam(n2) and
|
||||
DataFlow::localFlowStep(n1, n2)
|
||||
}
|
||||
|
||||
private predicate paramToUse(DataFlow::Node n1, DataFlow::Node n2) = fastTC(step/2)(n1, n2)
|
||||
|
||||
private predicate hasFlow(
|
||||
DataFlow::Node source, InitializeParameterInstruction init, DataFlow::Node sink
|
||||
) {
|
||||
pragma[only_bind_out](source.asParameter()) = pragma[only_bind_out](init.getParameter()) and
|
||||
paramToUse(source, sink) and
|
||||
isUse0(sink.asExpr())
|
||||
}
|
||||
|
||||
private InitializeParameterInstruction getAnAlwaysDereferencedParameter0() {
|
||||
exists(DataFlow::Node source, DataFlow::Node sink, IRBlock b1, int i1, IRBlock b2, int i2 |
|
||||
hasFlow(pragma[only_bind_into](source), result, pragma[only_bind_into](sink)) and
|
||||
source.hasIndexInBlock(b1, pragma[only_bind_into](i1)) and
|
||||
sink.hasIndexInBlock(b2, pragma[only_bind_into](i2)) and
|
||||
strictlyPostDominates(b2, i2, b1, i1)
|
||||
)
|
||||
}
|
||||
|
||||
private CallInstruction getAnAlwaysReachedCallInstruction() {
|
||||
exists(IRFunction f | result.getBlock().postDominates(f.getEntryBlock()))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate callHasTargetAndArgument(Function f, int i, Instruction argument) {
|
||||
exists(CallInstruction call |
|
||||
call.getStaticCallTarget() = f and
|
||||
call.getArgument(i) = argument and
|
||||
call = getAnAlwaysReachedCallInstruction()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate initializeParameterInFunction(Function f, int i) {
|
||||
exists(InitializeParameterInstruction init |
|
||||
pragma[only_bind_out](init.getEnclosingFunction()) = f and
|
||||
init.hasIndex(i) and
|
||||
init = getAnAlwaysDereferencedParameter()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate alwaysDereferencedArgumentHasValueNumber(ValueNumber vn) {
|
||||
exists(int i, Function f, Instruction argument |
|
||||
callHasTargetAndArgument(f, i, argument) and
|
||||
initializeParameterInFunction(pragma[only_bind_into](f), pragma[only_bind_into](i)) and
|
||||
vn.getAnInstruction() = argument
|
||||
)
|
||||
}
|
||||
|
||||
InitializeParameterInstruction getAnAlwaysDereferencedParameter() {
|
||||
result = getAnAlwaysDereferencedParameter0()
|
||||
or
|
||||
exists(ValueNumber vn |
|
||||
alwaysDereferencedArgumentHasValueNumber(vn) and
|
||||
vn.getAnInstruction() = result
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplCommon
|
||||
|
||||
/**
|
||||
* Holds if `n` represents the expression `e`, and `e` is a pointer that is
|
||||
* guaranteed to be dereferenced (either because it's an operand of a
|
||||
* dereference operation, or because it's an argument to a function that
|
||||
* always dereferences the parameter).
|
||||
*/
|
||||
predicate isUse(DataFlow::Node n, Expr e) {
|
||||
isUse0(e) and n.asExpr() = e
|
||||
or
|
||||
exists(CallInstruction call, InitializeParameterInstruction init |
|
||||
n.asOperand().getDef().getUnconvertedResultExpression() = e and
|
||||
pragma[only_bind_into](init) = ParameterSinks::getAnAlwaysDereferencedParameter() and
|
||||
viableParamArg(call, DataFlow::instructionNode(init), n) and
|
||||
pragma[only_bind_out](init.getEnclosingFunction()) =
|
||||
pragma[only_bind_out](call.getStaticCallTarget())
|
||||
)
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
description: Remove the old CFG tables
|
||||
compatibility: full
|
||||
|
||||
falsecond.rel: delete
|
||||
successors.rel: delete
|
||||
truecond.rel: delete
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
## 0.9.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `cpp/include-non-header` style query will now ignore the `.def` extension for textual header inclusions.
|
||||
|
||||
## 0.9.2
|
||||
|
||||
### New Queries
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.dataflow.new.DataFlow
|
||||
import FlowAfterFree
|
||||
import semmle.code.cpp.security.flowafterfree.FlowAfterFree
|
||||
import DoubleFree::PathGraph
|
||||
|
||||
/**
|
||||
@@ -22,26 +22,15 @@ import DoubleFree::PathGraph
|
||||
*/
|
||||
predicate isFree(DataFlow::Node n, Expr e) { isFree(_, n, e, _) }
|
||||
|
||||
/**
|
||||
* `dealloc1` is a deallocation expression and `e` is an expression such
|
||||
* that is deallocated by a deallocation expression, and the `(dealloc1, e)` pair
|
||||
* should be excluded by the `FlowFromFree` library.
|
||||
*
|
||||
* Note that `e` is not necessarily the expression deallocated by `dealloc1`. It will
|
||||
* be bound to the second deallocation as identified by the `FlowFromFree` library.
|
||||
*/
|
||||
bindingset[dealloc1, e]
|
||||
predicate isExcludeFreePair(DeallocationExpr dealloc1, Expr e) {
|
||||
exists(DeallocationExpr dealloc2 | isFree(_, _, e, dealloc2) |
|
||||
dealloc1.(FunctionCall).getTarget().hasGlobalName("MmFreePagesFromMdl") and
|
||||
// From https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-mmfreepagesfrommdl:
|
||||
// "After calling MmFreePagesFromMdl, the caller must also call ExFreePool
|
||||
// to release the memory that was allocated for the MDL structure."
|
||||
isExFreePoolCall(dealloc2, _)
|
||||
)
|
||||
module DoubleFreeParam implements FlowFromFreeParamSig {
|
||||
predicate isSink = isFree/2;
|
||||
|
||||
predicate isExcluded = isExcludedMmFreePageFromMdl/2;
|
||||
|
||||
predicate sourceSinkIsRelated = defaultSourceSinkIsRelated/2;
|
||||
}
|
||||
|
||||
module DoubleFree = FlowFromFree<isFree/2, isExcludeFreePair/2>;
|
||||
module DoubleFree = FlowFromFree<DoubleFreeParam>;
|
||||
|
||||
from DoubleFree::PathNode source, DoubleFree::PathNode sink, DeallocationExpr dealloc, Expr e2
|
||||
where
|
||||
|
||||
@@ -14,170 +14,25 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.dataflow.new.DataFlow
|
||||
import semmle.code.cpp.ir.IR
|
||||
import FlowAfterFree
|
||||
import UseAfterFree::PathGraph
|
||||
import semmle.code.cpp.security.flowafterfree.FlowAfterFree
|
||||
import semmle.code.cpp.security.flowafterfree.UseAfterFree
|
||||
import UseAfterFreeTrace::PathGraph
|
||||
|
||||
/**
|
||||
* Holds if `call` is a call to a function that obviously
|
||||
* doesn't dereference its `i`'th argument.
|
||||
*/
|
||||
private predicate externalCallNeverDereferences(FormattingFunctionCall call, int arg) {
|
||||
exists(int formatArg |
|
||||
pragma[only_bind_out](call.getFormatArgument(formatArg)) =
|
||||
pragma[only_bind_out](call.getArgument(arg)) and
|
||||
call.getFormat().(FormatLiteral).getConvSpec(formatArg) != "%s"
|
||||
)
|
||||
module UseAfterFreeParam implements FlowFromFreeParamSig {
|
||||
predicate isSink = isUse/2;
|
||||
|
||||
predicate isExcluded = isExcludedMmFreePageFromMdl/2;
|
||||
|
||||
predicate sourceSinkIsRelated = defaultSourceSinkIsRelated/2;
|
||||
}
|
||||
|
||||
predicate isUse0(Expr e) {
|
||||
not isFree(_, _, e, _) and
|
||||
(
|
||||
e = any(PointerDereferenceExpr pde).getOperand()
|
||||
or
|
||||
e = any(PointerFieldAccess pfa).getQualifier()
|
||||
or
|
||||
e = any(ArrayExpr ae).getArrayBase()
|
||||
or
|
||||
e = any(Call call).getQualifier()
|
||||
or
|
||||
// Assume any function without a body will dereference the pointer
|
||||
exists(int i, Call call, Function f |
|
||||
e = call.getArgument(i) and
|
||||
f = call.getTarget() and
|
||||
not f.hasEntryPoint() and
|
||||
// Exclude known functions we know won't dereference the pointer.
|
||||
// For example, a call such as `printf("%p", myPointer)`.
|
||||
not externalCallNeverDereferences(call, i)
|
||||
)
|
||||
)
|
||||
}
|
||||
import UseAfterFreeParam
|
||||
|
||||
module ParameterSinks {
|
||||
import semmle.code.cpp.ir.ValueNumbering
|
||||
module UseAfterFreeTrace = FlowFromFree<UseAfterFreeParam>;
|
||||
|
||||
predicate flowsToUse(DataFlow::Node n) {
|
||||
isUse0(n.asExpr())
|
||||
or
|
||||
exists(DataFlow::Node succ |
|
||||
flowsToUse(succ) and
|
||||
DataFlow::localFlowStep(n, succ)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate flowsFromParam(DataFlow::Node n) {
|
||||
flowsToUse(n) and
|
||||
(
|
||||
n.asParameter().getUnspecifiedType() instanceof PointerType
|
||||
or
|
||||
exists(DataFlow::Node prev |
|
||||
flowsFromParam(prev) and
|
||||
DataFlow::localFlowStep(prev, n)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate step(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
flowsFromParam(n1) and
|
||||
flowsFromParam(n2) and
|
||||
DataFlow::localFlowStep(n1, n2)
|
||||
}
|
||||
|
||||
private predicate paramToUse(DataFlow::Node n1, DataFlow::Node n2) = fastTC(step/2)(n1, n2)
|
||||
|
||||
private predicate hasFlow(
|
||||
DataFlow::Node source, InitializeParameterInstruction init, DataFlow::Node sink
|
||||
) {
|
||||
pragma[only_bind_out](source.asParameter()) = pragma[only_bind_out](init.getParameter()) and
|
||||
paramToUse(source, sink) and
|
||||
isUse0(sink.asExpr())
|
||||
}
|
||||
|
||||
private InitializeParameterInstruction getAnAlwaysDereferencedParameter0() {
|
||||
exists(DataFlow::Node source, DataFlow::Node sink, IRBlock b1, int i1, IRBlock b2, int i2 |
|
||||
hasFlow(pragma[only_bind_into](source), result, pragma[only_bind_into](sink)) and
|
||||
source.hasIndexInBlock(b1, pragma[only_bind_into](i1)) and
|
||||
sink.hasIndexInBlock(b2, pragma[only_bind_into](i2)) and
|
||||
strictlyPostDominates(b2, i2, b1, i1)
|
||||
)
|
||||
}
|
||||
|
||||
private CallInstruction getAnAlwaysReachedCallInstruction() {
|
||||
exists(IRFunction f | result.getBlock().postDominates(f.getEntryBlock()))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate callHasTargetAndArgument(Function f, int i, Instruction argument) {
|
||||
exists(CallInstruction call |
|
||||
call.getStaticCallTarget() = f and
|
||||
call.getArgument(i) = argument and
|
||||
call = getAnAlwaysReachedCallInstruction()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate initializeParameterInFunction(Function f, int i) {
|
||||
exists(InitializeParameterInstruction init |
|
||||
pragma[only_bind_out](init.getEnclosingFunction()) = f and
|
||||
init.hasIndex(i) and
|
||||
init = getAnAlwaysDereferencedParameter()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate alwaysDereferencedArgumentHasValueNumber(ValueNumber vn) {
|
||||
exists(int i, Function f, Instruction argument |
|
||||
callHasTargetAndArgument(f, i, argument) and
|
||||
initializeParameterInFunction(pragma[only_bind_into](f), pragma[only_bind_into](i)) and
|
||||
vn.getAnInstruction() = argument
|
||||
)
|
||||
}
|
||||
|
||||
InitializeParameterInstruction getAnAlwaysDereferencedParameter() {
|
||||
result = getAnAlwaysDereferencedParameter0()
|
||||
or
|
||||
exists(ValueNumber vn |
|
||||
alwaysDereferencedArgumentHasValueNumber(vn) and
|
||||
vn.getAnInstruction() = result
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module IsUse {
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplCommon
|
||||
|
||||
predicate isUse(DataFlow::Node n, Expr e) {
|
||||
isUse0(e) and n.asExpr() = e
|
||||
or
|
||||
exists(CallInstruction call, InitializeParameterInstruction init |
|
||||
n.asOperand().getDef().getUnconvertedResultExpression() = e and
|
||||
pragma[only_bind_into](init) = ParameterSinks::getAnAlwaysDereferencedParameter() and
|
||||
viableParamArg(call, DataFlow::instructionNode(init), n) and
|
||||
pragma[only_bind_out](init.getEnclosingFunction()) =
|
||||
pragma[only_bind_out](call.getStaticCallTarget())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import IsUse
|
||||
|
||||
/**
|
||||
* `dealloc1` is a deallocation expression, `e` is an expression that dereferences a
|
||||
* pointer, and the `(dealloc1, e)` pair should be excluded by the `FlowFromFree` library.
|
||||
*/
|
||||
bindingset[dealloc1, e]
|
||||
predicate isExcludeFreeUsePair(DeallocationExpr dealloc1, Expr e) {
|
||||
// From https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-mmfreepagesfrommdl:
|
||||
// "After calling MmFreePagesFromMdl, the caller must also call ExFreePool
|
||||
// to release the memory that was allocated for the MDL structure."
|
||||
dealloc1.(FunctionCall).getTarget().hasGlobalName("MmFreePagesFromMdl") and
|
||||
isExFreePoolCall(_, e)
|
||||
}
|
||||
|
||||
module UseAfterFree = FlowFromFree<isUse/2, isExcludeFreeUsePair/2>;
|
||||
|
||||
from UseAfterFree::PathNode source, UseAfterFree::PathNode sink, DeallocationExpr dealloc
|
||||
from UseAfterFreeTrace::PathNode source, UseAfterFreeTrace::PathNode sink, DeallocationExpr dealloc
|
||||
where
|
||||
UseAfterFree::flowPath(source, sink) and
|
||||
UseAfterFreeTrace::flowPath(source, sink) and
|
||||
isFree(source.getNode(), _, _, dealloc)
|
||||
select sink.getNode(), source, sink, "Memory may have been previously freed by $@.", dealloc,
|
||||
dealloc.toString()
|
||||
|
||||
@@ -22,9 +22,6 @@ class SalMacro extends Macro {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for SalMacro */
|
||||
deprecated class SALMacro = SalMacro;
|
||||
|
||||
pragma[noinline]
|
||||
private predicate isTopLevelMacroAccess(MacroAccess ma) { not exists(ma.getParentInvocation()) }
|
||||
|
||||
@@ -50,9 +47,6 @@ class SalAnnotation extends MacroInvocation {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for SalAnnotation */
|
||||
deprecated class SALAnnotation = SalAnnotation;
|
||||
|
||||
/**
|
||||
* A SAL macro indicating that the return value of a function should always be
|
||||
* checked.
|
||||
@@ -63,9 +57,6 @@ class SalCheckReturn extends SalAnnotation {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for SalCheckReturn */
|
||||
deprecated class SALCheckReturn = SalCheckReturn;
|
||||
|
||||
/**
|
||||
* A SAL macro indicating that a pointer variable or return value should not be
|
||||
* `NULL`.
|
||||
@@ -89,9 +80,6 @@ class SalNotNull extends SalAnnotation {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for SalNotNull */
|
||||
deprecated class SALNotNull = SalNotNull;
|
||||
|
||||
/**
|
||||
* A SAL macro indicating that a value may be `NULL`.
|
||||
*/
|
||||
@@ -105,9 +93,6 @@ class SalMaybeNull extends SalAnnotation {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for SalMaybeNull */
|
||||
deprecated class SALMaybeNull = SalMaybeNull;
|
||||
|
||||
/**
|
||||
* A parameter annotated by one or more SAL annotations.
|
||||
*/
|
||||
@@ -124,9 +109,6 @@ class SalParameter extends Parameter {
|
||||
predicate isInOut() { a.getMacroName().toLowerCase().matches("%\\_inout%") }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for SalParameter */
|
||||
deprecated class SALParameter = SalParameter;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Implementation details
|
||||
/**
|
||||
@@ -199,9 +181,6 @@ class SalElement extends Element {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for SalElement */
|
||||
deprecated class SALElement = SalElement;
|
||||
|
||||
/** Holds if `file` contains a SAL annotation. */
|
||||
pragma[noinline]
|
||||
private predicate containsSalAnnotation(File file) { any(SalAnnotation a).getFile() = file }
|
||||
|
||||
@@ -55,9 +55,6 @@ class SqlClientInfo extends SystemData {
|
||||
override predicate isSensitive() { any() }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for SqlClientInfo */
|
||||
deprecated class SQLClientInfo = SqlClientInfo;
|
||||
|
||||
private predicate sqlConnectInfo(FunctionCall source, Expr use) {
|
||||
(
|
||||
source.getTarget().hasName("mysql_connect") or
|
||||
@@ -77,9 +74,6 @@ class SqlConnectInfo extends SystemData {
|
||||
override predicate isSensitive() { any() }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for SqlConnectInfo */
|
||||
deprecated class SQLConnectInfo = SqlConnectInfo;
|
||||
|
||||
private predicate posixSystemInfo(FunctionCall source, DataFlow::Node use) {
|
||||
// size_t confstr(int name, char *buf, size_t len)
|
||||
// - various OS / system strings, such as the libc version
|
||||
|
||||
5
cpp/ql/src/change-notes/released/0.9.3.md
Normal file
5
cpp/ql/src/change-notes/released/0.9.3.md
Normal file
@@ -0,0 +1,5 @@
|
||||
## 0.9.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `cpp/include-non-header` style query will now ignore the `.def` extension for textual header inclusions.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.9.2
|
||||
lastReleaseVersion: 0.9.3
|
||||
|
||||
@@ -60,7 +60,7 @@ predicate computeHeuristicType(Type t) {
|
||||
|
||||
/**
|
||||
* Holds if `e` is an operation that is common in encryption-like computations.
|
||||
* Looking for clusters of these tends to find things like encrpytion,
|
||||
* Looking for clusters of these tends to find things like encryption,
|
||||
* compression, random number generation, graphics processing and other compute
|
||||
* heavy algorithms.
|
||||
*/
|
||||
|
||||
@@ -18,6 +18,7 @@ from Include i, File f, string extension
|
||||
where
|
||||
f = i.getIncludedFile() and
|
||||
extension = f.getExtension().toLowerCase() and
|
||||
extension != "def" and
|
||||
extension != "inc" and
|
||||
extension != "inl" and
|
||||
extension != "tcc" and
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 0.9.2
|
||||
version: 0.9.3
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
__builtin_foobar(i)i
|
||||
__builtin_malloc(i,i,i,f*)f
|
||||
@@ -1,4 +0,0 @@
|
||||
| file://:0:0:0:0 | __builtin_add_overflow | true | 0 | file://:0:0:0:0 | bool |
|
||||
| file://:0:0:0:0 | __builtin_foobar | true | 1 | file://:0:0:0:0 | int |
|
||||
| file://:0:0:0:0 | __builtin_malloc | true | 4 | file://:0:0:0:0 | float |
|
||||
| test.c:1:6:1:6 | f | false | 3 | file://:0:0:0:0 | long |
|
||||
@@ -1,5 +0,0 @@
|
||||
import cpp
|
||||
|
||||
from Function f, boolean isBuiltin
|
||||
where if f instanceof BuiltInFunction then isBuiltin = true else isBuiltin = false
|
||||
select f, isBuiltin, f.getNumberOfParameters(), f.getType()
|
||||
@@ -1,20 +0,0 @@
|
||||
long f(int a, int b, int c) {
|
||||
// A builtin from the builtin_functions_file.
|
||||
int i1 = __builtin_foobar(a);
|
||||
|
||||
// A builtin that's not in the file, but the extractor should handle, given the
|
||||
// --gnu_version flag we pass in.
|
||||
int i2;
|
||||
__builtin_add_overflow(a, b, &i2);
|
||||
|
||||
// A builtin that would normally be defined by the extractor with a type
|
||||
// expecting it to be called like this:
|
||||
//void* x = __builtin_malloc(a);
|
||||
// But we override the type in the builtin_functions_file so it's called like
|
||||
// this:
|
||||
float f1, f2;
|
||||
f1 = __builtin_malloc(a, b, c, &f2);
|
||||
|
||||
return 42;
|
||||
}
|
||||
// semmle-extractor-options: --gnu_version 50100 --edg --builtin_functions_file --edg ${testdir}/builtins.txt
|
||||
@@ -1,384 +1,388 @@
|
||||
| C::C | false | 493 | 493 | C |
|
||||
| C::C | false | 682 | 682 | C |
|
||||
| C::operator= | false | 675 | 675 | operator= |
|
||||
| C::~C | false | 614 | 614 | ~C |
|
||||
| Error::Error | false | 259 | 259 | Error |
|
||||
| Error::Error | false | 272 | 272 | Error |
|
||||
| Error::Error | false | 277 | 277 | return ... |
|
||||
| Error::Error | false | 279 | 279 | { ... } |
|
||||
| Error::Error | true | 277 | 272 | |
|
||||
| Error::Error | true | 279 | 277 | |
|
||||
| Error::operator= | false | 253 | 253 | operator= |
|
||||
| Error::~Error | false | 263 | 263 | ~Error |
|
||||
| Error::~Error | false | 268 | 268 | return ... |
|
||||
| Error::~Error | false | 270 | 270 | { ... } |
|
||||
| Error::~Error | true | 268 | 263 | |
|
||||
| Error::~Error | true | 270 | 268 | |
|
||||
| __va_list_tag::operator= | false | 140 | 140 | operator= |
|
||||
| __va_list_tag::operator= | false | 147 | 147 | operator= |
|
||||
| f | false | 477 | 477 | f |
|
||||
| f | false | 488 | 488 | declaration |
|
||||
| f | false | 491 | 491 | call to C |
|
||||
| f | false | 496 | 496 | 102 |
|
||||
| f | false | 497 | 497 | initializer for c102 |
|
||||
| f | false | 501 | 501 | call to C |
|
||||
| f | false | 505 | 505 | 103 |
|
||||
| f | false | 506 | 506 | initializer for c103 |
|
||||
| f | false | 509 | 509 | declaration |
|
||||
| f | false | 511 | 511 | b1 |
|
||||
| f | false | 513 | 513 | (bool)... |
|
||||
| f | false | 516 | 516 | 1 |
|
||||
| f | false | 517 | 517 | throw ... |
|
||||
| f | false | 519 | 519 | ExprStmt |
|
||||
| f | false | 521 | 521 | { ... } |
|
||||
| f | false | 523 | 523 | if (...) ... |
|
||||
| f | false | 525 | 525 | declaration |
|
||||
| f | false | 527 | 527 | { ... } |
|
||||
| f | false | 534 | 534 | 1 |
|
||||
| f | false | 536 | 536 | call to C |
|
||||
| f | false | 540 | 540 | 104 |
|
||||
| f | false | 541 | 541 | initializer for c104 |
|
||||
| f | false | 544 | 544 | declaration |
|
||||
| f | false | 546 | 546 | { ... } |
|
||||
| f | false | 548 | 548 | __try { ... } __except( ... ) { ... } |
|
||||
| f | false | 550 | 550 | declaration |
|
||||
| C::C | false | 499 | 499 | C |
|
||||
| C::C | false | 690 | 690 | C |
|
||||
| C::operator= | false | 681 | 681 | operator= |
|
||||
| C::~C | false | 647 | 647 | ~C |
|
||||
| Error::Error | false | 205 | 205 | Error |
|
||||
| Error::Error | false | 219 | 219 | Error |
|
||||
| Error::Error | false | 224 | 224 | return ... |
|
||||
| Error::Error | false | 226 | 226 | { ... } |
|
||||
| Error::Error | true | 224 | 219 | |
|
||||
| Error::Error | true | 226 | 224 | |
|
||||
| Error::operator= | false | 197 | 197 | operator= |
|
||||
| Error::~Error | false | 209 | 209 | ~Error |
|
||||
| Error::~Error | false | 215 | 215 | return ... |
|
||||
| Error::~Error | false | 217 | 217 | { ... } |
|
||||
| Error::~Error | true | 215 | 209 | |
|
||||
| Error::~Error | true | 217 | 215 | |
|
||||
| __va_list_tag::operator= | false | 66 | 66 | operator= |
|
||||
| __va_list_tag::operator= | false | 72 | 72 | operator= |
|
||||
| f | false | 483 | 483 | f |
|
||||
| f | false | 494 | 494 | declaration |
|
||||
| f | false | 497 | 497 | call to C |
|
||||
| f | false | 502 | 502 | 101 |
|
||||
| f | false | 503 | 503 | initializer for c101 |
|
||||
| f | false | 506 | 506 | __try { ... } __except( ... ) { ... } |
|
||||
| f | false | 509 | 509 | call to C |
|
||||
| f | false | 513 | 513 | 102 |
|
||||
| f | false | 514 | 514 | initializer for c102 |
|
||||
| f | false | 518 | 518 | call to C |
|
||||
| f | false | 522 | 522 | 103 |
|
||||
| f | false | 523 | 523 | initializer for c103 |
|
||||
| f | false | 526 | 526 | declaration |
|
||||
| f | false | 528 | 528 | if (...) ... |
|
||||
| f | false | 530 | 530 | b1 |
|
||||
| f | false | 532 | 532 | (bool)... |
|
||||
| f | false | 533 | 533 | ExprStmt |
|
||||
| f | false | 537 | 537 | 1 |
|
||||
| f | false | 538 | 538 | throw ... |
|
||||
| f | false | 540 | 540 | { ... } |
|
||||
| f | false | 542 | 542 | declaration |
|
||||
| f | false | 544 | 544 | { ... } |
|
||||
| f | false | 551 | 551 | 1 |
|
||||
| f | false | 553 | 553 | call to C |
|
||||
| f | false | 557 | 557 | 106 |
|
||||
| f | false | 558 | 558 | initializer for c106 |
|
||||
| f | false | 562 | 562 | call to C |
|
||||
| f | false | 566 | 566 | 107 |
|
||||
| f | false | 567 | 567 | initializer for c107 |
|
||||
| f | false | 570 | 570 | declaration |
|
||||
| f | false | 572 | 572 | b2 |
|
||||
| f | false | 574 | 574 | (bool)... |
|
||||
| f | false | 577 | 577 | 2 |
|
||||
| f | false | 578 | 578 | throw ... |
|
||||
| f | false | 580 | 580 | ExprStmt |
|
||||
| f | false | 582 | 582 | { ... } |
|
||||
| f | false | 584 | 584 | if (...) ... |
|
||||
| f | false | 586 | 586 | declaration |
|
||||
| f | false | 588 | 588 | { ... } |
|
||||
| f | false | 591 | 591 | call to C |
|
||||
| f | false | 595 | 595 | 108 |
|
||||
| f | false | 596 | 596 | initializer for c108 |
|
||||
| f | false | 599 | 599 | declaration |
|
||||
| f | false | 601 | 601 | { ... } |
|
||||
| f | false | 603 | 603 | __try { ... } __finally { ... } |
|
||||
| f | false | 605 | 605 | declaration |
|
||||
| f | false | 607 | 607 | return ... |
|
||||
| f | false | 609 | 609 | { ... } |
|
||||
| f | false | 611 | 611 | c101 |
|
||||
| f | false | 613 | 613 | call to c101.~C |
|
||||
| f | false | 615 | 615 | c105 |
|
||||
| f | false | 616 | 616 | call to c105.~C |
|
||||
| f | false | 617 | 617 | c109 |
|
||||
| f | false | 618 | 618 | call to c109.~C |
|
||||
| f | false | 619 | 619 | c101 |
|
||||
| f | false | 620 | 620 | call to c101.~C |
|
||||
| f | false | 621 | 621 | c105 |
|
||||
| f | false | 622 | 622 | call to c105.~C |
|
||||
| f | false | 623 | 623 | c108 |
|
||||
| f | false | 625 | 625 | call to c108.~C |
|
||||
| f | false | 626 | 626 | c106 |
|
||||
| f | false | 628 | 628 | call to c106.~C |
|
||||
| f | false | 629 | 629 | c107 |
|
||||
| f | false | 630 | 630 | call to c107.~C |
|
||||
| f | false | 631 | 631 | c106 |
|
||||
| f | false | 632 | 632 | call to c106.~C |
|
||||
| f | false | 633 | 633 | c104 |
|
||||
| f | false | 635 | 635 | call to c104.~C |
|
||||
| f | false | 636 | 636 | c102 |
|
||||
| f | false | 638 | 638 | call to c102.~C |
|
||||
| f | false | 639 | 639 | c103 |
|
||||
| f | false | 640 | 640 | call to c103.~C |
|
||||
| f | false | 641 | 641 | c102 |
|
||||
| f | false | 642 | 642 | call to c102.~C |
|
||||
| f | false | 644 | 644 | call to C |
|
||||
| f | false | 648 | 648 | 101 |
|
||||
| f | false | 649 | 649 | initializer for c101 |
|
||||
| f | false | 653 | 653 | call to C |
|
||||
| f | false | 657 | 657 | 105 |
|
||||
| f | false | 658 | 658 | initializer for c105 |
|
||||
| f | false | 662 | 662 | call to C |
|
||||
| f | false | 666 | 666 | 109 |
|
||||
| f | false | 667 | 667 | initializer for c109 |
|
||||
| f | true | 488 | 649 | |
|
||||
| f | true | 491 | 523 | |
|
||||
| f | true | 496 | 491 | |
|
||||
| f | true | 497 | 496 | |
|
||||
| f | true | 501 | 639 | |
|
||||
| f | true | 505 | 501 | |
|
||||
| f | true | 506 | 505 | |
|
||||
| f | true | 509 | 497 | |
|
||||
| f | true | 511 | 521 | T |
|
||||
| f | true | 511 | 525 | F |
|
||||
| f | true | 516 | 517 | |
|
||||
| f | true | 517 | 641 | |
|
||||
| f | true | 519 | 516 | |
|
||||
| f | true | 521 | 519 | |
|
||||
| f | true | 523 | 511 | |
|
||||
| f | true | 525 | 506 | |
|
||||
| f | true | 527 | 509 | |
|
||||
| f | true | 534 | 546 | T |
|
||||
| f | true | 536 | 633 | |
|
||||
| f | true | 540 | 536 | |
|
||||
| f | true | 541 | 540 | |
|
||||
| f | true | 544 | 541 | |
|
||||
| f | true | 546 | 544 | |
|
||||
| f | true | 548 | 527 | |
|
||||
| f | true | 550 | 658 | |
|
||||
| f | true | 553 | 584 | |
|
||||
| f | false | 557 | 557 | 104 |
|
||||
| f | false | 558 | 558 | initializer for c104 |
|
||||
| f | false | 561 | 561 | declaration |
|
||||
| f | false | 563 | 563 | { ... } |
|
||||
| f | false | 565 | 565 | declaration |
|
||||
| f | false | 568 | 568 | call to C |
|
||||
| f | false | 572 | 572 | 105 |
|
||||
| f | false | 573 | 573 | initializer for c105 |
|
||||
| f | false | 576 | 576 | __try { ... } __finally { ... } |
|
||||
| f | false | 579 | 579 | call to C |
|
||||
| f | false | 583 | 583 | 106 |
|
||||
| f | false | 584 | 584 | initializer for c106 |
|
||||
| f | false | 588 | 588 | call to C |
|
||||
| f | false | 592 | 592 | 107 |
|
||||
| f | false | 593 | 593 | initializer for c107 |
|
||||
| f | false | 596 | 596 | declaration |
|
||||
| f | false | 598 | 598 | if (...) ... |
|
||||
| f | false | 600 | 600 | b2 |
|
||||
| f | false | 602 | 602 | (bool)... |
|
||||
| f | false | 603 | 603 | ExprStmt |
|
||||
| f | false | 607 | 607 | 2 |
|
||||
| f | false | 608 | 608 | throw ... |
|
||||
| f | false | 610 | 610 | { ... } |
|
||||
| f | false | 612 | 612 | declaration |
|
||||
| f | false | 614 | 614 | { ... } |
|
||||
| f | false | 617 | 617 | call to C |
|
||||
| f | false | 621 | 621 | 108 |
|
||||
| f | false | 622 | 622 | initializer for c108 |
|
||||
| f | false | 625 | 625 | declaration |
|
||||
| f | false | 627 | 627 | { ... } |
|
||||
| f | false | 629 | 629 | declaration |
|
||||
| f | false | 632 | 632 | call to C |
|
||||
| f | false | 636 | 636 | 109 |
|
||||
| f | false | 637 | 637 | initializer for c109 |
|
||||
| f | false | 640 | 640 | return ... |
|
||||
| f | false | 642 | 642 | { ... } |
|
||||
| f | false | 644 | 644 | c104 |
|
||||
| f | false | 646 | 646 | call to c104.~C |
|
||||
| f | false | 648 | 648 | c101 |
|
||||
| f | false | 650 | 650 | call to c101.~C |
|
||||
| f | false | 651 | 651 | c102 |
|
||||
| f | false | 653 | 653 | call to c102.~C |
|
||||
| f | false | 654 | 654 | c103 |
|
||||
| f | false | 655 | 655 | call to c103.~C |
|
||||
| f | false | 656 | 656 | c102 |
|
||||
| f | false | 657 | 657 | call to c102.~C |
|
||||
| f | false | 658 | 658 | c101 |
|
||||
| f | false | 659 | 659 | call to c101.~C |
|
||||
| f | false | 660 | 660 | c105 |
|
||||
| f | false | 661 | 661 | call to c105.~C |
|
||||
| f | false | 662 | 662 | c108 |
|
||||
| f | false | 664 | 664 | call to c108.~C |
|
||||
| f | false | 665 | 665 | c106 |
|
||||
| f | false | 667 | 667 | call to c106.~C |
|
||||
| f | false | 668 | 668 | c107 |
|
||||
| f | false | 669 | 669 | call to c107.~C |
|
||||
| f | false | 670 | 670 | c106 |
|
||||
| f | false | 671 | 671 | call to c106.~C |
|
||||
| f | false | 672 | 672 | c101 |
|
||||
| f | false | 673 | 673 | call to c101.~C |
|
||||
| f | false | 674 | 674 | c105 |
|
||||
| f | false | 675 | 675 | call to c105.~C |
|
||||
| f | false | 676 | 676 | c109 |
|
||||
| f | false | 677 | 677 | call to c109.~C |
|
||||
| f | true | 494 | 503 | |
|
||||
| f | true | 497 | 506 | |
|
||||
| f | true | 502 | 497 | |
|
||||
| f | true | 503 | 502 | |
|
||||
| f | true | 506 | 544 | |
|
||||
| f | true | 509 | 528 | |
|
||||
| f | true | 513 | 509 | |
|
||||
| f | true | 514 | 513 | |
|
||||
| f | true | 518 | 654 | |
|
||||
| f | true | 522 | 518 | |
|
||||
| f | true | 523 | 522 | |
|
||||
| f | true | 526 | 514 | |
|
||||
| f | true | 528 | 530 | |
|
||||
| f | true | 530 | 540 | T |
|
||||
| f | true | 530 | 542 | F |
|
||||
| f | true | 533 | 537 | |
|
||||
| f | true | 537 | 538 | |
|
||||
| f | true | 538 | 656 | |
|
||||
| f | true | 540 | 533 | |
|
||||
| f | true | 542 | 523 | |
|
||||
| f | true | 544 | 526 | |
|
||||
| f | true | 551 | 563 | T |
|
||||
| f | true | 553 | 644 | |
|
||||
| f | true | 557 | 553 | |
|
||||
| f | true | 558 | 557 | |
|
||||
| f | true | 562 | 629 | |
|
||||
| f | true | 566 | 562 | |
|
||||
| f | true | 567 | 566 | |
|
||||
| f | true | 570 | 558 | |
|
||||
| f | true | 572 | 582 | T |
|
||||
| f | true | 572 | 586 | F |
|
||||
| f | true | 577 | 578 | |
|
||||
| f | true | 578 | 631 | |
|
||||
| f | true | 580 | 577 | |
|
||||
| f | true | 582 | 580 | |
|
||||
| f | true | 584 | 572 | |
|
||||
| f | true | 586 | 567 | |
|
||||
| f | true | 588 | 570 | |
|
||||
| f | true | 591 | 623 | |
|
||||
| f | true | 595 | 591 | |
|
||||
| f | true | 596 | 595 | |
|
||||
| f | true | 599 | 596 | |
|
||||
| f | true | 601 | 599 | |
|
||||
| f | true | 603 | 588 | |
|
||||
| f | true | 605 | 667 | |
|
||||
| f | true | 607 | 617 | |
|
||||
| f | true | 609 | 488 | |
|
||||
| f | true | 611 | 613 | |
|
||||
| f | true | 613 | 477 | |
|
||||
| f | true | 615 | 616 | |
|
||||
| f | true | 616 | 611 | |
|
||||
| f | true | 617 | 618 | |
|
||||
| f | true | 618 | 615 | |
|
||||
| f | true | 619 | 620 | |
|
||||
| f | true | 620 | 477 | |
|
||||
| f | true | 621 | 622 | |
|
||||
| f | true | 622 | 619 | |
|
||||
| f | true | 623 | 625 | |
|
||||
| f | true | 625 | 605 | |
|
||||
| f | true | 625 | 621 | |
|
||||
| f | true | 626 | 628 | |
|
||||
| f | true | 628 | 601 | |
|
||||
| f | true | 629 | 630 | |
|
||||
| f | true | 630 | 626 | |
|
||||
| f | true | 631 | 632 | |
|
||||
| f | true | 632 | 601 | |
|
||||
| f | true | 633 | 635 | |
|
||||
| f | true | 635 | 550 | |
|
||||
| f | true | 636 | 638 | |
|
||||
| f | true | 638 | 550 | |
|
||||
| f | true | 639 | 640 | |
|
||||
| f | true | 640 | 636 | |
|
||||
| f | true | 641 | 642 | |
|
||||
| f | true | 642 | 534 | |
|
||||
| f | true | 644 | 548 | |
|
||||
| f | true | 648 | 644 | |
|
||||
| f | true | 649 | 648 | |
|
||||
| f | true | 653 | 603 | |
|
||||
| f | true | 657 | 653 | |
|
||||
| f | true | 658 | 657 | |
|
||||
| f | true | 662 | 607 | |
|
||||
| f | true | 666 | 662 | |
|
||||
| f | true | 667 | 666 | |
|
||||
| f1 | false | 292 | 292 | f1 |
|
||||
| f2 | false | 299 | 299 | f2 |
|
||||
| f3 | false | 304 | 304 | f3 |
|
||||
| f4 | false | 309 | 309 | f4 |
|
||||
| f4 | false | 433 | 433 | return ... |
|
||||
| f4 | false | 435 | 435 | { ... } |
|
||||
| f4 | true | 433 | 309 | |
|
||||
| f4 | true | 435 | 433 | |
|
||||
| f5 | false | 314 | 314 | f5 |
|
||||
| f5 | false | 422 | 422 | 3 |
|
||||
| f5 | false | 423 | 423 | throw ... |
|
||||
| f5 | false | 425 | 425 | ExprStmt |
|
||||
| f5 | false | 427 | 427 | { ... } |
|
||||
| f5 | true | 422 | 423 | |
|
||||
| f5 | true | 423 | 314 | |
|
||||
| f5 | true | 425 | 422 | |
|
||||
| f5 | true | 427 | 425 | |
|
||||
| fun | false | 287 | 287 | fun |
|
||||
| fun | false | 295 | 295 | call to f1 |
|
||||
| f | true | 561 | 558 | |
|
||||
| f | true | 563 | 561 | |
|
||||
| f | true | 565 | 573 | |
|
||||
| f | true | 568 | 576 | |
|
||||
| f | true | 572 | 568 | |
|
||||
| f | true | 573 | 572 | |
|
||||
| f | true | 576 | 614 | |
|
||||
| f | true | 579 | 598 | |
|
||||
| f | true | 583 | 579 | |
|
||||
| f | true | 584 | 583 | |
|
||||
| f | true | 588 | 668 | |
|
||||
| f | true | 592 | 588 | |
|
||||
| f | true | 593 | 592 | |
|
||||
| f | true | 596 | 584 | |
|
||||
| f | true | 598 | 600 | |
|
||||
| f | true | 600 | 610 | T |
|
||||
| f | true | 600 | 612 | F |
|
||||
| f | true | 603 | 607 | |
|
||||
| f | true | 607 | 608 | |
|
||||
| f | true | 608 | 670 | |
|
||||
| f | true | 610 | 603 | |
|
||||
| f | true | 612 | 593 | |
|
||||
| f | true | 614 | 596 | |
|
||||
| f | true | 617 | 662 | |
|
||||
| f | true | 621 | 617 | |
|
||||
| f | true | 622 | 621 | |
|
||||
| f | true | 625 | 622 | |
|
||||
| f | true | 627 | 625 | |
|
||||
| f | true | 629 | 637 | |
|
||||
| f | true | 632 | 640 | |
|
||||
| f | true | 636 | 632 | |
|
||||
| f | true | 637 | 636 | |
|
||||
| f | true | 640 | 676 | |
|
||||
| f | true | 642 | 494 | |
|
||||
| f | true | 644 | 646 | |
|
||||
| f | true | 646 | 565 | |
|
||||
| f | true | 648 | 650 | |
|
||||
| f | true | 650 | 483 | |
|
||||
| f | true | 651 | 653 | |
|
||||
| f | true | 653 | 565 | |
|
||||
| f | true | 654 | 655 | |
|
||||
| f | true | 655 | 651 | |
|
||||
| f | true | 656 | 657 | |
|
||||
| f | true | 657 | 551 | |
|
||||
| f | true | 658 | 659 | |
|
||||
| f | true | 659 | 483 | |
|
||||
| f | true | 660 | 661 | |
|
||||
| f | true | 661 | 658 | |
|
||||
| f | true | 662 | 664 | |
|
||||
| f | true | 664 | 629 | |
|
||||
| f | true | 664 | 660 | |
|
||||
| f | true | 665 | 667 | |
|
||||
| f | true | 667 | 627 | |
|
||||
| f | true | 668 | 669 | |
|
||||
| f | true | 669 | 665 | |
|
||||
| f | true | 670 | 671 | |
|
||||
| f | true | 671 | 627 | |
|
||||
| f | true | 672 | 673 | |
|
||||
| f | true | 673 | 483 | |
|
||||
| f | true | 674 | 675 | |
|
||||
| f | true | 675 | 672 | |
|
||||
| f | true | 676 | 677 | |
|
||||
| f | true | 677 | 674 | |
|
||||
| f1 | false | 287 | 287 | f1 |
|
||||
| f2 | false | 294 | 294 | f2 |
|
||||
| f3 | false | 299 | 299 | f3 |
|
||||
| f4 | false | 304 | 304 | f4 |
|
||||
| f4 | false | 422 | 422 | return ... |
|
||||
| f4 | false | 424 | 424 | { ... } |
|
||||
| f4 | true | 422 | 304 | |
|
||||
| f4 | true | 424 | 422 | |
|
||||
| f5 | false | 309 | 309 | f5 |
|
||||
| f5 | false | 409 | 409 | ExprStmt |
|
||||
| f5 | false | 413 | 413 | 3 |
|
||||
| f5 | false | 414 | 414 | throw ... |
|
||||
| f5 | false | 416 | 416 | { ... } |
|
||||
| f5 | true | 409 | 413 | |
|
||||
| f5 | true | 413 | 414 | |
|
||||
| f5 | true | 414 | 309 | |
|
||||
| f5 | true | 416 | 409 | |
|
||||
| fun | false | 276 | 276 | fun |
|
||||
| fun | false | 281 | 281 | try { ... } |
|
||||
| fun | false | 283 | 283 | try { ... } |
|
||||
| fun | false | 285 | 285 | ExprStmt |
|
||||
| fun | false | 290 | 290 | call to f1 |
|
||||
| fun | false | 292 | 292 | ExprStmt |
|
||||
| fun | false | 295 | 295 | call to f2 |
|
||||
| fun | false | 297 | 297 | ExprStmt |
|
||||
| fun | false | 300 | 300 | call to f2 |
|
||||
| fun | false | 300 | 300 | call to f3 |
|
||||
| fun | false | 302 | 302 | ExprStmt |
|
||||
| fun | false | 305 | 305 | call to f3 |
|
||||
| fun | false | 305 | 305 | call to f4 |
|
||||
| fun | false | 307 | 307 | ExprStmt |
|
||||
| fun | false | 310 | 310 | call to f4 |
|
||||
| fun | false | 310 | 310 | call to f5 |
|
||||
| fun | false | 312 | 312 | ExprStmt |
|
||||
| fun | false | 315 | 315 | call to f5 |
|
||||
| fun | false | 317 | 317 | ExprStmt |
|
||||
| fun | false | 321 | 321 | 5 |
|
||||
| fun | false | 322 | 322 | throw ... |
|
||||
| fun | false | 324 | 324 | ExprStmt |
|
||||
| fun | false | 327 | 327 | call to g |
|
||||
| fun | false | 316 | 316 | 5 |
|
||||
| fun | false | 317 | 317 | throw ... |
|
||||
| fun | false | 319 | 319 | ExprStmt |
|
||||
| fun | false | 322 | 322 | call to g |
|
||||
| fun | false | 324 | 324 | { ... } |
|
||||
| fun | false | 329 | 329 | ExprStmt |
|
||||
| fun | false | 331 | 331 | { ... } |
|
||||
| fun | false | 337 | 337 | call to h |
|
||||
| fun | false | 339 | 339 | ExprStmt |
|
||||
| fun | false | 341 | 341 | { ... } |
|
||||
| fun | false | 343 | 343 | <handler> |
|
||||
| fun | false | 344 | 344 | try { ... } |
|
||||
| fun | false | 346 | 346 | { ... } |
|
||||
| fun | false | 352 | 352 | call to i |
|
||||
| fun | false | 354 | 354 | ExprStmt |
|
||||
| fun | false | 356 | 356 | { ... } |
|
||||
| fun | false | 362 | 362 | call to j |
|
||||
| fun | false | 364 | 364 | ExprStmt |
|
||||
| fun | false | 366 | 366 | { ... } |
|
||||
| fun | false | 368 | 368 | <handler> |
|
||||
| fun | false | 369 | 369 | <handler> |
|
||||
| fun | false | 370 | 370 | try { ... } |
|
||||
| fun | false | 373 | 373 | call to k |
|
||||
| fun | false | 375 | 375 | ExprStmt |
|
||||
| fun | false | 379 | 379 | 7 |
|
||||
| fun | false | 380 | 380 | throw ... |
|
||||
| fun | false | 382 | 382 | ExprStmt |
|
||||
| fun | false | 384 | 384 | { ... } |
|
||||
| fun | false | 390 | 390 | call to l |
|
||||
| fun | false | 392 | 392 | ExprStmt |
|
||||
| fun | false | 394 | 394 | { ... } |
|
||||
| fun | false | 397 | 397 | call to m |
|
||||
| fun | false | 399 | 399 | ExprStmt |
|
||||
| fun | false | 401 | 401 | { ... } |
|
||||
| fun | false | 403 | 403 | <handler> |
|
||||
| fun | false | 404 | 404 | <handler> |
|
||||
| fun | false | 405 | 405 | try { ... } |
|
||||
| fun | false | 408 | 408 | call to n |
|
||||
| fun | false | 410 | 410 | ExprStmt |
|
||||
| fun | false | 412 | 412 | return ... |
|
||||
| fun | false | 414 | 414 | { ... } |
|
||||
| fun | true | 295 | 302 | |
|
||||
| fun | true | 297 | 295 | |
|
||||
| fun | true | 300 | 307 | |
|
||||
| fun | true | 302 | 300 | |
|
||||
| fun | true | 305 | 312 | |
|
||||
| fun | true | 307 | 305 | |
|
||||
| fun | true | 310 | 317 | |
|
||||
| fun | true | 312 | 310 | |
|
||||
| fun | true | 317 | 315 | |
|
||||
| fun | true | 321 | 322 | |
|
||||
| fun | true | 322 | 343 | |
|
||||
| fun | true | 324 | 321 | |
|
||||
| fun | true | 327 | 375 | |
|
||||
| fun | true | 329 | 327 | |
|
||||
| fun | true | 331 | 297 | |
|
||||
| fun | true | 337 | 375 | |
|
||||
| fun | true | 339 | 337 | |
|
||||
| fun | true | 341 | 339 | |
|
||||
| fun | true | 343 | 341 | |
|
||||
| fun | true | 343 | 368 | |
|
||||
| fun | true | 344 | 331 | |
|
||||
| fun | true | 346 | 344 | |
|
||||
| fun | true | 352 | 375 | |
|
||||
| fun | true | 354 | 352 | |
|
||||
| fun | true | 356 | 354 | |
|
||||
| fun | true | 362 | 375 | |
|
||||
| fun | true | 364 | 362 | |
|
||||
| fun | true | 366 | 364 | |
|
||||
| fun | true | 368 | 356 | |
|
||||
| fun | true | 368 | 369 | |
|
||||
| fun | true | 369 | 287 | |
|
||||
| fun | true | 369 | 366 | |
|
||||
| fun | true | 370 | 346 | |
|
||||
| fun | true | 373 | 405 | |
|
||||
| fun | true | 375 | 373 | |
|
||||
| fun | true | 379 | 380 | |
|
||||
| fun | true | 380 | 403 | |
|
||||
| fun | true | 382 | 379 | |
|
||||
| fun | true | 384 | 382 | |
|
||||
| fun | true | 390 | 410 | |
|
||||
| fun | true | 392 | 390 | |
|
||||
| fun | true | 394 | 392 | |
|
||||
| fun | true | 397 | 410 | |
|
||||
| fun | true | 399 | 397 | |
|
||||
| fun | true | 401 | 399 | |
|
||||
| fun | true | 403 | 394 | |
|
||||
| fun | true | 403 | 404 | |
|
||||
| fun | true | 404 | 401 | |
|
||||
| fun | true | 405 | 384 | |
|
||||
| fun | true | 408 | 412 | |
|
||||
| fun | true | 410 | 408 | |
|
||||
| fun | true | 412 | 287 | |
|
||||
| fun | true | 414 | 370 | |
|
||||
| fun2 | false | 204 | 204 | fun2 |
|
||||
| fun2 | false | 215 | 215 | fun2 |
|
||||
| fun2 | false | 218 | 218 | { ... } |
|
||||
| fun2 | false | 223 | 223 | re-throw exception |
|
||||
| fun2 | false | 225 | 225 | ExprStmt |
|
||||
| fun2 | false | 227 | 227 | { ... } |
|
||||
| fun2 | false | 231 | 231 | 1 |
|
||||
| fun2 | false | 232 | 232 | return ... |
|
||||
| fun2 | false | 234 | 234 | { ... } |
|
||||
| fun2 | false | 236 | 236 | <handler> |
|
||||
| fun2 | false | 237 | 237 | <handler> |
|
||||
| fun2 | false | 238 | 238 | try { ... } |
|
||||
| fun2 | false | 242 | 242 | 0 |
|
||||
| fun2 | false | 243 | 243 | return ... |
|
||||
| fun2 | false | 245 | 245 | { ... } |
|
||||
| fun2 | false | 702 | 702 | { ... } |
|
||||
| fun2 | false | 707 | 707 | re-throw exception |
|
||||
| fun2 | false | 708 | 708 | ExprStmt |
|
||||
| fun2 | false | 709 | 709 | { ... } |
|
||||
| fun2 | false | 711 | 711 | 1 |
|
||||
| fun2 | false | 712 | 712 | return ... |
|
||||
| fun2 | false | 713 | 713 | { ... } |
|
||||
| fun2 | false | 714 | 714 | <handler> |
|
||||
| fun2 | false | 715 | 715 | <handler> |
|
||||
| fun2 | false | 716 | 716 | try { ... } |
|
||||
| fun2 | false | 718 | 718 | 0 |
|
||||
| fun2 | false | 719 | 719 | return ... |
|
||||
| fun2 | false | 720 | 720 | { ... } |
|
||||
| fun2 | true | 218 | 243 | |
|
||||
| fun2 | true | 223 | 215 | |
|
||||
| fun2 | true | 225 | 223 | |
|
||||
| fun2 | true | 227 | 225 | |
|
||||
| fun2 | true | 231 | 215 | |
|
||||
| fun2 | true | 232 | 231 | |
|
||||
| fun2 | true | 234 | 232 | |
|
||||
| fun2 | true | 236 | 227 | |
|
||||
| fun2 | true | 236 | 237 | |
|
||||
| fun2 | true | 237 | 234 | |
|
||||
| fun2 | true | 238 | 218 | |
|
||||
| fun2 | true | 242 | 215 | |
|
||||
| fun2 | true | 243 | 242 | |
|
||||
| fun2 | true | 245 | 238 | |
|
||||
| fun2 | true | 702 | 719 | |
|
||||
| fun2 | true | 707 | 204 | |
|
||||
| fun2 | true | 708 | 707 | |
|
||||
| fun2 | true | 709 | 708 | |
|
||||
| fun2 | true | 711 | 204 | |
|
||||
| fun2 | true | 712 | 711 | |
|
||||
| fun2 | true | 713 | 712 | |
|
||||
| fun2 | true | 714 | 709 | |
|
||||
| fun2 | true | 714 | 715 | |
|
||||
| fun2 | true | 715 | 713 | |
|
||||
| fun2 | true | 716 | 702 | |
|
||||
| fun2 | true | 718 | 204 | |
|
||||
| fun2 | true | 719 | 718 | |
|
||||
| fun2 | true | 720 | 716 | |
|
||||
| g | false | 326 | 326 | g |
|
||||
| h | false | 336 | 336 | h |
|
||||
| i | false | 351 | 351 | i |
|
||||
| j | false | 361 | 361 | j |
|
||||
| k | false | 372 | 372 | k |
|
||||
| l | false | 389 | 389 | l |
|
||||
| m | false | 396 | 396 | m |
|
||||
| n | false | 407 | 407 | n |
|
||||
| run_fun2 | false | 199 | 199 | run_fun2 |
|
||||
| run_fun2 | false | 207 | 207 | call to fun2 |
|
||||
| run_fun2 | false | 209 | 209 | ExprStmt |
|
||||
| run_fun2 | false | 211 | 211 | return ... |
|
||||
| run_fun2 | false | 213 | 213 | { ... } |
|
||||
| run_fun2 | true | 207 | 211 | |
|
||||
| run_fun2 | true | 209 | 207 | |
|
||||
| run_fun2 | true | 211 | 199 | |
|
||||
| run_fun2 | true | 213 | 209 | |
|
||||
| fun | false | 332 | 332 | call to h |
|
||||
| fun | false | 334 | 334 | { ... } |
|
||||
| fun | false | 336 | 336 | <handler> |
|
||||
| fun | false | 337 | 337 | { ... } |
|
||||
| fun | false | 342 | 342 | ExprStmt |
|
||||
| fun | false | 345 | 345 | call to i |
|
||||
| fun | false | 347 | 347 | { ... } |
|
||||
| fun | false | 352 | 352 | ExprStmt |
|
||||
| fun | false | 355 | 355 | call to j |
|
||||
| fun | false | 357 | 357 | { ... } |
|
||||
| fun | false | 359 | 359 | <handler> |
|
||||
| fun | false | 360 | 360 | <handler> |
|
||||
| fun | false | 361 | 361 | ExprStmt |
|
||||
| fun | false | 364 | 364 | call to k |
|
||||
| fun | false | 366 | 366 | try { ... } |
|
||||
| fun | false | 368 | 368 | ExprStmt |
|
||||
| fun | false | 372 | 372 | 7 |
|
||||
| fun | false | 373 | 373 | throw ... |
|
||||
| fun | false | 375 | 375 | { ... } |
|
||||
| fun | false | 380 | 380 | ExprStmt |
|
||||
| fun | false | 383 | 383 | call to l |
|
||||
| fun | false | 385 | 385 | { ... } |
|
||||
| fun | false | 387 | 387 | ExprStmt |
|
||||
| fun | false | 390 | 390 | call to m |
|
||||
| fun | false | 392 | 392 | { ... } |
|
||||
| fun | false | 394 | 394 | <handler> |
|
||||
| fun | false | 395 | 395 | <handler> |
|
||||
| fun | false | 396 | 396 | ExprStmt |
|
||||
| fun | false | 399 | 399 | call to n |
|
||||
| fun | false | 401 | 401 | return ... |
|
||||
| fun | false | 403 | 403 | { ... } |
|
||||
| fun | true | 281 | 337 | |
|
||||
| fun | true | 283 | 324 | |
|
||||
| fun | true | 285 | 290 | |
|
||||
| fun | true | 290 | 292 | |
|
||||
| fun | true | 292 | 295 | |
|
||||
| fun | true | 295 | 297 | |
|
||||
| fun | true | 297 | 300 | |
|
||||
| fun | true | 300 | 302 | |
|
||||
| fun | true | 302 | 305 | |
|
||||
| fun | true | 305 | 307 | |
|
||||
| fun | true | 307 | 310 | |
|
||||
| fun | true | 312 | 316 | |
|
||||
| fun | true | 316 | 317 | |
|
||||
| fun | true | 317 | 336 | |
|
||||
| fun | true | 319 | 322 | |
|
||||
| fun | true | 322 | 361 | |
|
||||
| fun | true | 324 | 285 | |
|
||||
| fun | true | 329 | 332 | |
|
||||
| fun | true | 332 | 361 | |
|
||||
| fun | true | 334 | 329 | |
|
||||
| fun | true | 336 | 334 | |
|
||||
| fun | true | 336 | 359 | |
|
||||
| fun | true | 337 | 283 | |
|
||||
| fun | true | 342 | 345 | |
|
||||
| fun | true | 345 | 361 | |
|
||||
| fun | true | 347 | 342 | |
|
||||
| fun | true | 352 | 355 | |
|
||||
| fun | true | 355 | 361 | |
|
||||
| fun | true | 357 | 352 | |
|
||||
| fun | true | 359 | 347 | |
|
||||
| fun | true | 359 | 360 | |
|
||||
| fun | true | 360 | 276 | |
|
||||
| fun | true | 360 | 357 | |
|
||||
| fun | true | 361 | 364 | |
|
||||
| fun | true | 364 | 366 | |
|
||||
| fun | true | 366 | 375 | |
|
||||
| fun | true | 368 | 372 | |
|
||||
| fun | true | 372 | 373 | |
|
||||
| fun | true | 373 | 394 | |
|
||||
| fun | true | 375 | 368 | |
|
||||
| fun | true | 380 | 383 | |
|
||||
| fun | true | 383 | 396 | |
|
||||
| fun | true | 385 | 380 | |
|
||||
| fun | true | 387 | 390 | |
|
||||
| fun | true | 390 | 396 | |
|
||||
| fun | true | 392 | 387 | |
|
||||
| fun | true | 394 | 385 | |
|
||||
| fun | true | 394 | 395 | |
|
||||
| fun | true | 395 | 392 | |
|
||||
| fun | true | 396 | 399 | |
|
||||
| fun | true | 399 | 401 | |
|
||||
| fun | true | 401 | 276 | |
|
||||
| fun | true | 403 | 281 | |
|
||||
| fun2 | false | 149 | 149 | fun2 |
|
||||
| fun2 | false | 159 | 159 | fun2 |
|
||||
| fun2 | false | 162 | 162 | try { ... } |
|
||||
| fun2 | false | 164 | 164 | { ... } |
|
||||
| fun2 | false | 172 | 172 | ExprStmt |
|
||||
| fun2 | false | 174 | 174 | re-throw exception |
|
||||
| fun2 | false | 176 | 176 | { ... } |
|
||||
| fun2 | false | 178 | 178 | return ... |
|
||||
| fun2 | false | 182 | 182 | 1 |
|
||||
| fun2 | false | 183 | 183 | { ... } |
|
||||
| fun2 | false | 185 | 185 | <handler> |
|
||||
| fun2 | false | 186 | 186 | <handler> |
|
||||
| fun2 | false | 187 | 187 | return ... |
|
||||
| fun2 | false | 191 | 191 | 0 |
|
||||
| fun2 | false | 192 | 192 | { ... } |
|
||||
| fun2 | false | 257 | 257 | try { ... } |
|
||||
| fun2 | false | 258 | 258 | { ... } |
|
||||
| fun2 | false | 261 | 261 | ExprStmt |
|
||||
| fun2 | false | 262 | 262 | re-throw exception |
|
||||
| fun2 | false | 263 | 263 | { ... } |
|
||||
| fun2 | false | 264 | 264 | return ... |
|
||||
| fun2 | false | 266 | 266 | 1 |
|
||||
| fun2 | false | 267 | 267 | { ... } |
|
||||
| fun2 | false | 268 | 268 | <handler> |
|
||||
| fun2 | false | 269 | 269 | <handler> |
|
||||
| fun2 | false | 270 | 270 | return ... |
|
||||
| fun2 | false | 272 | 272 | 0 |
|
||||
| fun2 | false | 273 | 273 | { ... } |
|
||||
| fun2 | true | 162 | 164 | |
|
||||
| fun2 | true | 164 | 187 | |
|
||||
| fun2 | true | 172 | 174 | |
|
||||
| fun2 | true | 174 | 159 | |
|
||||
| fun2 | true | 176 | 172 | |
|
||||
| fun2 | true | 178 | 182 | |
|
||||
| fun2 | true | 182 | 159 | |
|
||||
| fun2 | true | 183 | 178 | |
|
||||
| fun2 | true | 185 | 176 | |
|
||||
| fun2 | true | 185 | 186 | |
|
||||
| fun2 | true | 186 | 183 | |
|
||||
| fun2 | true | 187 | 191 | |
|
||||
| fun2 | true | 191 | 159 | |
|
||||
| fun2 | true | 192 | 162 | |
|
||||
| fun2 | true | 257 | 258 | |
|
||||
| fun2 | true | 258 | 270 | |
|
||||
| fun2 | true | 261 | 262 | |
|
||||
| fun2 | true | 262 | 149 | |
|
||||
| fun2 | true | 263 | 261 | |
|
||||
| fun2 | true | 264 | 266 | |
|
||||
| fun2 | true | 266 | 149 | |
|
||||
| fun2 | true | 267 | 264 | |
|
||||
| fun2 | true | 268 | 263 | |
|
||||
| fun2 | true | 268 | 269 | |
|
||||
| fun2 | true | 269 | 267 | |
|
||||
| fun2 | true | 270 | 272 | |
|
||||
| fun2 | true | 272 | 149 | |
|
||||
| fun2 | true | 273 | 257 | |
|
||||
| g | false | 321 | 321 | g |
|
||||
| h | false | 331 | 331 | h |
|
||||
| i | false | 344 | 344 | i |
|
||||
| j | false | 354 | 354 | j |
|
||||
| k | false | 363 | 363 | k |
|
||||
| l | false | 382 | 382 | l |
|
||||
| m | false | 389 | 389 | m |
|
||||
| n | false | 398 | 398 | n |
|
||||
| run_fun2 | false | 142 | 142 | run_fun2 |
|
||||
| run_fun2 | false | 147 | 147 | ExprStmt |
|
||||
| run_fun2 | false | 152 | 152 | call to fun2 |
|
||||
| run_fun2 | false | 154 | 154 | return ... |
|
||||
| run_fun2 | false | 156 | 156 | { ... } |
|
||||
| run_fun2 | true | 147 | 152 | |
|
||||
| run_fun2 | true | 152 | 154 | |
|
||||
| run_fun2 | true | 154 | 142 | |
|
||||
| run_fun2 | true | 156 | 147 | |
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
| exceptions.cpp:25:13:25:19 | ExprStmt |
|
||||
| exceptions.cpp:26:13:26:13 | ExprStmt |
|
||||
| ms.cpp:38:1:38:1 | c101 |
|
||||
|
||||
@@ -159,6 +159,9 @@ postWithInFlow
|
||||
| test.cpp:808:5:808:21 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:808:6:808:21 | global_indirect1 [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:832:5:832:17 | global_direct [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:931:5:931:18 | global_pointer [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:932:5:932:19 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:932:6:932:19 | global_pointer [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
@@ -166,3 +169,4 @@ uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
lambdaCallEnclosingCallableMismatch
|
||||
|
||||
@@ -31,3 +31,4 @@ uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
lambdaCallEnclosingCallableMismatch
|
||||
|
||||
@@ -300,6 +300,7 @@ irFlow
|
||||
| test.cpp:902:56:902:75 | *indirect_source(2) | test.cpp:911:19:911:48 | *global_array_static_indirect_2 |
|
||||
| test.cpp:914:46:914:53 | source | test.cpp:919:10:919:30 | global_pointer_static |
|
||||
| test.cpp:915:57:915:76 | *indirect_source(1) | test.cpp:921:19:921:50 | *global_pointer_static_indirect_1 |
|
||||
| test.cpp:932:23:932:28 | call to source | test.cpp:937:10:937:24 | * ... |
|
||||
| true_upon_entry.cpp:9:11:9:16 | call to source | true_upon_entry.cpp:13:8:13:8 | x |
|
||||
| true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x |
|
||||
| true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x |
|
||||
|
||||
@@ -922,4 +922,18 @@ namespace GlobalArrays {
|
||||
sink(global_pointer_static_indirect_2); // clean: global_pointer_static_indirect_2 does not have 2 indirections
|
||||
indirect_sink(global_pointer_static_indirect_2); // clean: global_pointer_static_indirect_2 does not have 2 indirections
|
||||
}
|
||||
}
|
||||
|
||||
namespace global_variable_conflation_test {
|
||||
int* global_pointer;
|
||||
|
||||
void def() {
|
||||
global_pointer = nullptr;
|
||||
*global_pointer = source();
|
||||
}
|
||||
|
||||
void use() {
|
||||
sink(global_pointer); // clean
|
||||
sink(*global_pointer); // $ ir MISSING: ast
|
||||
}
|
||||
}
|
||||
@@ -193,3 +193,4 @@ uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
lambdaCallEnclosingCallableMismatch
|
||||
|
||||
@@ -27,3 +27,4 @@ uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
lambdaCallEnclosingCallableMismatch
|
||||
|
||||
@@ -12,8 +12,6 @@ edges
|
||||
| A.cpp:31:20:31:20 | c | A.cpp:31:14:31:21 | call to B [c] |
|
||||
| A.cpp:41:5:41:6 | insert output argument | A.cpp:43:10:43:12 | *& ... |
|
||||
| A.cpp:41:15:41:21 | new | A.cpp:41:5:41:6 | insert output argument |
|
||||
| A.cpp:41:15:41:21 | new | A.cpp:41:5:41:6 | insert output argument |
|
||||
| A.cpp:41:15:41:21 | new | A.cpp:41:15:41:21 | new |
|
||||
| A.cpp:47:12:47:18 | new | A.cpp:48:20:48:20 | c |
|
||||
| A.cpp:48:12:48:18 | *call to make [c] | A.cpp:49:10:49:10 | *b [c] |
|
||||
| A.cpp:48:20:48:20 | c | A.cpp:29:23:29:23 | c |
|
||||
@@ -22,7 +20,6 @@ edges
|
||||
| A.cpp:55:5:55:5 | set output argument [c] | A.cpp:56:10:56:10 | *b [c] |
|
||||
| A.cpp:55:12:55:19 | new | A.cpp:27:17:27:17 | c |
|
||||
| A.cpp:55:12:55:19 | new | A.cpp:55:5:55:5 | set output argument [c] |
|
||||
| A.cpp:55:12:55:19 | new | A.cpp:55:12:55:19 | new |
|
||||
| A.cpp:56:10:56:10 | *b [c] | A.cpp:28:8:28:10 | *this [c] |
|
||||
| A.cpp:56:10:56:10 | *b [c] | A.cpp:56:10:56:17 | call to get |
|
||||
| A.cpp:57:11:57:24 | *new [c] | A.cpp:28:8:28:10 | *this [c] |
|
||||
@@ -33,12 +30,10 @@ edges
|
||||
| A.cpp:57:17:57:23 | new | A.cpp:57:17:57:23 | new |
|
||||
| A.cpp:64:10:64:15 | *call to setOnB [c] | A.cpp:66:10:66:11 | *b2 [c] |
|
||||
| A.cpp:64:21:64:28 | new | A.cpp:64:10:64:15 | *call to setOnB [c] |
|
||||
| A.cpp:64:21:64:28 | new | A.cpp:64:21:64:28 | new |
|
||||
| A.cpp:64:21:64:28 | new | A.cpp:85:26:85:26 | c |
|
||||
| A.cpp:66:10:66:11 | *b2 [c] | A.cpp:66:10:66:14 | c |
|
||||
| A.cpp:73:10:73:19 | *call to setOnBWrap [c] | A.cpp:75:10:75:11 | *b2 [c] |
|
||||
| A.cpp:73:25:73:32 | new | A.cpp:73:10:73:19 | *call to setOnBWrap [c] |
|
||||
| A.cpp:73:25:73:32 | new | A.cpp:73:25:73:32 | new |
|
||||
| A.cpp:73:25:73:32 | new | A.cpp:78:27:78:27 | c |
|
||||
| A.cpp:75:10:75:11 | *b2 [c] | A.cpp:75:10:75:14 | c |
|
||||
| A.cpp:78:27:78:27 | c | A.cpp:81:21:81:21 | c |
|
||||
@@ -770,7 +765,6 @@ nodes
|
||||
| A.cpp:31:20:31:20 | c | semmle.label | c |
|
||||
| A.cpp:41:5:41:6 | insert output argument | semmle.label | insert output argument |
|
||||
| A.cpp:41:15:41:21 | new | semmle.label | new |
|
||||
| A.cpp:41:15:41:21 | new | semmle.label | new |
|
||||
| A.cpp:43:10:43:12 | *& ... | semmle.label | *& ... |
|
||||
| A.cpp:47:12:47:18 | new | semmle.label | new |
|
||||
| A.cpp:48:12:48:18 | *call to make [c] | semmle.label | *call to make [c] |
|
||||
@@ -779,7 +773,6 @@ nodes
|
||||
| A.cpp:49:10:49:13 | c | semmle.label | c |
|
||||
| A.cpp:55:5:55:5 | set output argument [c] | semmle.label | set output argument [c] |
|
||||
| A.cpp:55:12:55:19 | new | semmle.label | new |
|
||||
| A.cpp:55:12:55:19 | new | semmle.label | new |
|
||||
| A.cpp:56:10:56:10 | *b [c] | semmle.label | *b [c] |
|
||||
| A.cpp:56:10:56:17 | call to get | semmle.label | call to get |
|
||||
| A.cpp:57:10:57:32 | call to get | semmle.label | call to get |
|
||||
@@ -789,12 +782,10 @@ nodes
|
||||
| A.cpp:57:17:57:23 | new | semmle.label | new |
|
||||
| A.cpp:64:10:64:15 | *call to setOnB [c] | semmle.label | *call to setOnB [c] |
|
||||
| A.cpp:64:21:64:28 | new | semmle.label | new |
|
||||
| A.cpp:64:21:64:28 | new | semmle.label | new |
|
||||
| A.cpp:66:10:66:11 | *b2 [c] | semmle.label | *b2 [c] |
|
||||
| A.cpp:66:10:66:14 | c | semmle.label | c |
|
||||
| A.cpp:73:10:73:19 | *call to setOnBWrap [c] | semmle.label | *call to setOnBWrap [c] |
|
||||
| A.cpp:73:25:73:32 | new | semmle.label | new |
|
||||
| A.cpp:73:25:73:32 | new | semmle.label | new |
|
||||
| A.cpp:75:10:75:11 | *b2 [c] | semmle.label | *b2 [c] |
|
||||
| A.cpp:75:10:75:14 | c | semmle.label | c |
|
||||
| A.cpp:78:6:78:15 | **setOnBWrap [c] | semmle.label | **setOnBWrap [c] |
|
||||
@@ -1608,14 +1599,10 @@ subpaths
|
||||
| simple.cpp:84:14:84:20 | *this [f2, f1] | simple.cpp:78:9:78:15 | *this [f2, f1] | simple.cpp:78:9:78:15 | *getf2f1 | simple.cpp:84:14:84:20 | call to getf2f1 |
|
||||
#select
|
||||
| A.cpp:43:10:43:12 | *& ... | A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | *& ... | *& ... flows from $@ | A.cpp:41:15:41:21 | new | new |
|
||||
| A.cpp:43:10:43:12 | *& ... | A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | *& ... | *& ... flows from $@ | A.cpp:41:15:41:21 | new | new |
|
||||
| A.cpp:49:10:49:13 | c | A.cpp:47:12:47:18 | new | A.cpp:49:10:49:13 | c | c flows from $@ | A.cpp:47:12:47:18 | new | new |
|
||||
| A.cpp:56:10:56:17 | call to get | A.cpp:55:12:55:19 | new | A.cpp:56:10:56:17 | call to get | call to get flows from $@ | A.cpp:55:12:55:19 | new | new |
|
||||
| A.cpp:56:10:56:17 | call to get | A.cpp:55:12:55:19 | new | A.cpp:56:10:56:17 | call to get | call to get flows from $@ | A.cpp:55:12:55:19 | new | new |
|
||||
| A.cpp:57:10:57:32 | call to get | A.cpp:57:17:57:23 | new | A.cpp:57:10:57:32 | call to get | call to get flows from $@ | A.cpp:57:17:57:23 | new | new |
|
||||
| A.cpp:66:10:66:14 | c | A.cpp:64:21:64:28 | new | A.cpp:66:10:66:14 | c | c flows from $@ | A.cpp:64:21:64:28 | new | new |
|
||||
| A.cpp:66:10:66:14 | c | A.cpp:64:21:64:28 | new | A.cpp:66:10:66:14 | c | c flows from $@ | A.cpp:64:21:64:28 | new | new |
|
||||
| A.cpp:75:10:75:14 | c | A.cpp:73:25:73:32 | new | A.cpp:75:10:75:14 | c | c flows from $@ | A.cpp:73:25:73:32 | new | new |
|
||||
| A.cpp:75:10:75:14 | c | A.cpp:73:25:73:32 | new | A.cpp:75:10:75:14 | c | c flows from $@ | A.cpp:73:25:73:32 | new | new |
|
||||
| A.cpp:107:12:107:16 | a | A.cpp:98:12:98:18 | new | A.cpp:107:12:107:16 | a | a flows from $@ | A.cpp:98:12:98:18 | new | new |
|
||||
| A.cpp:120:12:120:16 | a | A.cpp:98:12:98:18 | new | A.cpp:120:12:120:16 | a | a flows from $@ | A.cpp:98:12:98:18 | new | new |
|
||||
|
||||
@@ -1,255 +1,263 @@
|
||||
| C::C | false | 197 | 197 | C |
|
||||
| C::C | false | 398 | 398 | C |
|
||||
| C::operator= | false | 391 | 391 | operator= |
|
||||
| C::~C | false | 331 | 331 | ~C |
|
||||
| Class2::Class2 | false | 538 | 538 | Class2 |
|
||||
| Class2::Class2 | false | 544 | 544 | return ... |
|
||||
| Class2::Class2 | false | 546 | 546 | { ... } |
|
||||
| C::C | false | 181 | 181 | C |
|
||||
| C::C | false | 384 | 384 | C |
|
||||
| C::operator= | false | 375 | 375 | operator= |
|
||||
| C::~C | false | 333 | 333 | ~C |
|
||||
| Class2::Class2 | false | 547 | 547 | Class2 |
|
||||
| Class2::Class2 | true | 544 | 538 | |
|
||||
| Class2::Class2 | true | 546 | 544 | |
|
||||
| Class2::operator= | false | 532 | 532 | operator= |
|
||||
| Class2::~Class2 | false | 467 | 467 | ~Class2 |
|
||||
| Outer::Inner::Inner | false | 488 | 488 | Inner |
|
||||
| Outer::Inner::Inner | false | 509 | 509 | Inner |
|
||||
| Outer::Inner::Inner | false | 528 | 528 | return ... |
|
||||
| Outer::Inner::Inner | false | 530 | 530 | { ... } |
|
||||
| Outer::Inner::Inner | true | 528 | 488 | |
|
||||
| Outer::Inner::Inner | true | 530 | 528 | |
|
||||
| Outer::Inner::operator= | false | 502 | 502 | operator= |
|
||||
| Outer::Inner::~Inner | false | 470 | 470 | ~Inner |
|
||||
| Outer::Inner::~Inner | false | 517 | 517 | return ... |
|
||||
| Outer::Inner::~Inner | false | 519 | 519 | { ... } |
|
||||
| Outer::Inner::~Inner | true | 517 | 470 | |
|
||||
| Outer::Inner::~Inner | true | 519 | 517 | |
|
||||
| Outer::f2 | false | 439 | 439 | f2 |
|
||||
| Outer::f2 | false | 447 | 447 | declaration |
|
||||
| Outer::f2 | false | 449 | 449 | i |
|
||||
| Outer::f2 | false | 451 | 451 | (bool)... |
|
||||
| Outer::f2 | false | 452 | 452 | return ... |
|
||||
| Outer::f2 | false | 454 | 454 | { ... } |
|
||||
| Outer::f2 | false | 456 | 456 | if (...) ... |
|
||||
| Outer::f2 | false | 458 | 458 | declaration |
|
||||
| Outer::f2 | false | 460 | 460 | return ... |
|
||||
| Outer::f2 | false | 462 | 462 | { ... } |
|
||||
| Outer::f2 | false | 464 | 464 | c |
|
||||
| Outer::f2 | false | 466 | 466 | call to c.~Class2 |
|
||||
| Outer::f2 | false | 468 | 468 | inner |
|
||||
| Outer::f2 | false | 469 | 469 | call to inner.~Inner |
|
||||
| Outer::f2 | false | 474 | 474 | call to getClass2 |
|
||||
| Outer::f2 | false | 476 | 476 | initializer for c |
|
||||
| Outer::f2 | false | 481 | 481 | call to Inner |
|
||||
| Outer::f2 | false | 490 | 490 | c |
|
||||
| Outer::f2 | false | 492 | 492 | (const Class2)... |
|
||||
| Outer::f2 | false | 493 | 493 | (reference to) |
|
||||
| Outer::f2 | false | 494 | 494 | initializer for inner |
|
||||
| Outer::f2 | true | 447 | 476 | |
|
||||
| Outer::f2 | true | 449 | 454 | T |
|
||||
| Outer::f2 | true | 449 | 458 | F |
|
||||
| Outer::f2 | true | 452 | 464 | |
|
||||
| Outer::f2 | true | 454 | 452 | |
|
||||
| Outer::f2 | true | 456 | 449 | |
|
||||
| Outer::f2 | true | 458 | 494 | |
|
||||
| Outer::f2 | true | 460 | 468 | |
|
||||
| Outer::f2 | true | 462 | 447 | |
|
||||
| Class2::Class2 | false | 554 | 554 | return ... |
|
||||
| Class2::Class2 | false | 556 | 556 | { ... } |
|
||||
| Class2::Class2 | false | 557 | 557 | Class2 |
|
||||
| Class2::Class2 | true | 554 | 547 | |
|
||||
| Class2::Class2 | true | 556 | 554 | |
|
||||
| Class2::operator= | false | 541 | 541 | operator= |
|
||||
| Class2::~Class2 | false | 499 | 499 | ~Class2 |
|
||||
| Outer::Inner::Inner | false | 481 | 481 | Inner |
|
||||
| Outer::Inner::Inner | false | 517 | 517 | Inner |
|
||||
| Outer::Inner::Inner | false | 537 | 537 | return ... |
|
||||
| Outer::Inner::Inner | false | 539 | 539 | { ... } |
|
||||
| Outer::Inner::Inner | true | 537 | 481 | |
|
||||
| Outer::Inner::Inner | true | 539 | 537 | |
|
||||
| Outer::Inner::operator= | false | 508 | 508 | operator= |
|
||||
| Outer::Inner::~Inner | false | 504 | 504 | ~Inner |
|
||||
| Outer::Inner::~Inner | false | 526 | 526 | return ... |
|
||||
| Outer::Inner::~Inner | false | 528 | 528 | { ... } |
|
||||
| Outer::Inner::~Inner | true | 526 | 504 | |
|
||||
| Outer::Inner::~Inner | true | 528 | 526 | |
|
||||
| Outer::f2 | false | 444 | 444 | f2 |
|
||||
| Outer::f2 | false | 453 | 453 | declaration |
|
||||
| Outer::f2 | false | 458 | 458 | call to getClass2 |
|
||||
| Outer::f2 | false | 460 | 460 | initializer for c |
|
||||
| Outer::f2 | false | 464 | 464 | if (...) ... |
|
||||
| Outer::f2 | false | 466 | 466 | i |
|
||||
| Outer::f2 | false | 468 | 468 | (bool)... |
|
||||
| Outer::f2 | false | 469 | 469 | return ... |
|
||||
| Outer::f2 | false | 471 | 471 | { ... } |
|
||||
| Outer::f2 | false | 473 | 473 | declaration |
|
||||
| Outer::f2 | false | 476 | 476 | call to Inner |
|
||||
| Outer::f2 | false | 482 | 482 | c |
|
||||
| Outer::f2 | false | 485 | 485 | (const Class2)... |
|
||||
| Outer::f2 | false | 488 | 488 | (reference to) |
|
||||
| Outer::f2 | false | 489 | 489 | initializer for inner |
|
||||
| Outer::f2 | false | 492 | 492 | return ... |
|
||||
| Outer::f2 | false | 494 | 494 | { ... } |
|
||||
| Outer::f2 | false | 496 | 496 | c |
|
||||
| Outer::f2 | false | 498 | 498 | call to c.~Class2 |
|
||||
| Outer::f2 | false | 500 | 500 | c |
|
||||
| Outer::f2 | false | 501 | 501 | call to c.~Class2 |
|
||||
| Outer::f2 | false | 502 | 502 | inner |
|
||||
| Outer::f2 | false | 503 | 503 | call to inner.~Inner |
|
||||
| Outer::f2 | true | 453 | 460 | |
|
||||
| Outer::f2 | true | 458 | 464 | |
|
||||
| Outer::f2 | true | 460 | 458 | |
|
||||
| Outer::f2 | true | 464 | 466 | |
|
||||
| Outer::f2 | true | 466 | 439 | |
|
||||
| Outer::f2 | true | 468 | 469 | |
|
||||
| Outer::f2 | true | 469 | 464 | |
|
||||
| Outer::f2 | true | 474 | 456 | |
|
||||
| Outer::f2 | true | 476 | 474 | |
|
||||
| Outer::f2 | true | 481 | 460 | |
|
||||
| Outer::f2 | true | 490 | 481 | |
|
||||
| Outer::f2 | true | 494 | 490 | |
|
||||
| Outer::operator= | false | 424 | 424 | operator= |
|
||||
| Outer::operator= | false | 435 | 435 | operator= |
|
||||
| __va_list_tag::operator= | false | 93 | 93 | operator= |
|
||||
| __va_list_tag::operator= | false | 100 | 100 | operator= |
|
||||
| f | false | 181 | 181 | f |
|
||||
| f | false | 192 | 192 | declaration |
|
||||
| f | false | 195 | 195 | call to C |
|
||||
| f | false | 200 | 200 | 120 |
|
||||
| f | false | 201 | 201 | initializer for c20 |
|
||||
| f | false | 205 | 205 | call to C |
|
||||
| f | false | 209 | 209 | 121 |
|
||||
| f | false | 210 | 210 | initializer for c21 |
|
||||
| f | false | 213 | 213 | declaration |
|
||||
| f | false | 216 | 216 | call to C |
|
||||
| f | false | 220 | 220 | 130 |
|
||||
| f | false | 221 | 221 | initializer for c30 |
|
||||
| f | false | 224 | 224 | declaration |
|
||||
| f | false | 226 | 226 | { ... } |
|
||||
| f | false | 229 | 229 | call to C |
|
||||
| f | false | 233 | 233 | 131 |
|
||||
| f | false | 234 | 234 | initializer for c31 |
|
||||
| f | false | 238 | 238 | call to C |
|
||||
| f | false | 242 | 242 | 132 |
|
||||
| f | false | 243 | 243 | initializer for c32 |
|
||||
| f | false | 247 | 247 | call to C |
|
||||
| f | false | 251 | 251 | 133 |
|
||||
| f | false | 252 | 252 | initializer for c33 |
|
||||
| f | false | 255 | 255 | declaration |
|
||||
| f | false | 257 | 257 | b1 |
|
||||
| f | false | 259 | 259 | (bool)... |
|
||||
| f | false | 260 | 260 | goto ... |
|
||||
| f | false | 262 | 262 | if (...) ... |
|
||||
| f | false | 264 | 264 | declaration |
|
||||
| f | false | 266 | 266 | b2 |
|
||||
| f | false | 268 | 268 | (bool)... |
|
||||
| f | false | 269 | 269 | return ... |
|
||||
| f | false | 271 | 271 | if (...) ... |
|
||||
| f | false | 273 | 273 | declaration |
|
||||
| f | false | 275 | 275 | { ... } |
|
||||
| f | false | 278 | 278 | call to C |
|
||||
| f | false | 282 | 282 | 134 |
|
||||
| f | false | 283 | 283 | initializer for c34 |
|
||||
| f | false | 286 | 286 | declaration |
|
||||
| f | false | 288 | 288 | { ... } |
|
||||
| f | false | 290 | 290 | declaration |
|
||||
| f | false | 292 | 292 | { ... } |
|
||||
| f | false | 295 | 295 | call to C |
|
||||
| f | false | 299 | 299 | 122 |
|
||||
| f | false | 300 | 300 | initializer for c22 |
|
||||
| f | false | 303 | 303 | declaration |
|
||||
| f | false | 305 | 305 | { ... } |
|
||||
| f | false | 308 | 308 | call to C |
|
||||
| f | false | 312 | 312 | 123 |
|
||||
| f | false | 313 | 313 | initializer for c23 |
|
||||
| f | false | 316 | 316 | label ...: |
|
||||
| f | false | 318 | 318 | declaration |
|
||||
| f | false | 320 | 320 | { ... } |
|
||||
| f | false | 322 | 322 | declaration |
|
||||
| f | false | 324 | 324 | return ... |
|
||||
| f | false | 326 | 326 | { ... } |
|
||||
| f | false | 328 | 328 | c10 |
|
||||
| f | false | 330 | 330 | call to c10.~C |
|
||||
| f | false | 332 | 332 | c11 |
|
||||
| f | false | 333 | 333 | call to c11.~C |
|
||||
| f | false | 334 | 334 | c23 |
|
||||
| f | false | 336 | 336 | call to c23.~C |
|
||||
| f | false | 337 | 337 | c22 |
|
||||
| f | false | 339 | 339 | call to c22.~C |
|
||||
| f | false | 340 | 340 | c20 |
|
||||
| f | false | 342 | 342 | call to c20.~C |
|
||||
| f | false | 343 | 343 | c21 |
|
||||
| f | false | 344 | 344 | call to c21.~C |
|
||||
| f | false | 345 | 345 | c34 |
|
||||
| f | false | 347 | 347 | call to c34.~C |
|
||||
| Outer::f2 | true | 466 | 471 | T |
|
||||
| Outer::f2 | true | 466 | 473 | F |
|
||||
| Outer::f2 | true | 469 | 496 | |
|
||||
| Outer::f2 | true | 471 | 469 | |
|
||||
| Outer::f2 | true | 473 | 489 | |
|
||||
| Outer::f2 | true | 476 | 492 | |
|
||||
| Outer::f2 | true | 482 | 476 | |
|
||||
| Outer::f2 | true | 489 | 482 | |
|
||||
| Outer::f2 | true | 492 | 502 | |
|
||||
| Outer::f2 | true | 494 | 453 | |
|
||||
| Outer::f2 | true | 496 | 498 | |
|
||||
| Outer::f2 | true | 498 | 444 | |
|
||||
| Outer::f2 | true | 500 | 501 | |
|
||||
| Outer::f2 | true | 501 | 444 | |
|
||||
| Outer::f2 | true | 502 | 503 | |
|
||||
| Outer::f2 | true | 503 | 500 | |
|
||||
| Outer::operator= | false | 428 | 428 | operator= |
|
||||
| Outer::operator= | false | 438 | 438 | operator= |
|
||||
| __va_list_tag::operator= | false | 66 | 66 | operator= |
|
||||
| __va_list_tag::operator= | false | 72 | 72 | operator= |
|
||||
| f | false | 165 | 165 | f |
|
||||
| f | false | 176 | 176 | declaration |
|
||||
| f | false | 179 | 179 | call to C |
|
||||
| f | false | 184 | 184 | 110 |
|
||||
| f | false | 185 | 185 | initializer for c10 |
|
||||
| f | false | 189 | 189 | call to C |
|
||||
| f | false | 193 | 193 | 120 |
|
||||
| f | false | 194 | 194 | initializer for c20 |
|
||||
| f | false | 198 | 198 | call to C |
|
||||
| f | false | 202 | 202 | 121 |
|
||||
| f | false | 203 | 203 | initializer for c21 |
|
||||
| f | false | 206 | 206 | declaration |
|
||||
| f | false | 209 | 209 | call to C |
|
||||
| f | false | 213 | 213 | 130 |
|
||||
| f | false | 214 | 214 | initializer for c30 |
|
||||
| f | false | 217 | 217 | declaration |
|
||||
| f | false | 219 | 219 | { ... } |
|
||||
| f | false | 222 | 222 | call to C |
|
||||
| f | false | 226 | 226 | 131 |
|
||||
| f | false | 227 | 227 | initializer for c31 |
|
||||
| f | false | 231 | 231 | call to C |
|
||||
| f | false | 235 | 235 | 132 |
|
||||
| f | false | 236 | 236 | initializer for c32 |
|
||||
| f | false | 240 | 240 | call to C |
|
||||
| f | false | 244 | 244 | 133 |
|
||||
| f | false | 245 | 245 | initializer for c33 |
|
||||
| f | false | 248 | 248 | declaration |
|
||||
| f | false | 250 | 250 | if (...) ... |
|
||||
| f | false | 252 | 252 | b1 |
|
||||
| f | false | 254 | 254 | (bool)... |
|
||||
| f | false | 255 | 255 | goto ... |
|
||||
| f | false | 257 | 257 | declaration |
|
||||
| f | false | 259 | 259 | if (...) ... |
|
||||
| f | false | 261 | 261 | b2 |
|
||||
| f | false | 263 | 263 | (bool)... |
|
||||
| f | false | 264 | 264 | return ... |
|
||||
| f | false | 266 | 266 | declaration |
|
||||
| f | false | 268 | 268 | { ... } |
|
||||
| f | false | 271 | 271 | call to C |
|
||||
| f | false | 275 | 275 | 134 |
|
||||
| f | false | 276 | 276 | initializer for c34 |
|
||||
| f | false | 279 | 279 | declaration |
|
||||
| f | false | 281 | 281 | { ... } |
|
||||
| f | false | 283 | 283 | declaration |
|
||||
| f | false | 285 | 285 | { ... } |
|
||||
| f | false | 288 | 288 | call to C |
|
||||
| f | false | 292 | 292 | 122 |
|
||||
| f | false | 293 | 293 | initializer for c22 |
|
||||
| f | false | 296 | 296 | declaration |
|
||||
| f | false | 298 | 298 | { ... } |
|
||||
| f | false | 301 | 301 | call to C |
|
||||
| f | false | 305 | 305 | 123 |
|
||||
| f | false | 306 | 306 | initializer for c23 |
|
||||
| f | false | 309 | 309 | label ...: |
|
||||
| f | false | 311 | 311 | declaration |
|
||||
| f | false | 313 | 313 | { ... } |
|
||||
| f | false | 315 | 315 | declaration |
|
||||
| f | false | 318 | 318 | call to C |
|
||||
| f | false | 322 | 322 | 111 |
|
||||
| f | false | 323 | 323 | initializer for c11 |
|
||||
| f | false | 326 | 326 | return ... |
|
||||
| f | false | 328 | 328 | { ... } |
|
||||
| f | false | 330 | 330 | c20 |
|
||||
| f | false | 332 | 332 | call to c20.~C |
|
||||
| f | false | 334 | 334 | c21 |
|
||||
| f | false | 335 | 335 | call to c21.~C |
|
||||
| f | false | 336 | 336 | c30 |
|
||||
| f | false | 338 | 338 | call to c30.~C |
|
||||
| f | false | 339 | 339 | c31 |
|
||||
| f | false | 341 | 341 | call to c31.~C |
|
||||
| f | false | 342 | 342 | c32 |
|
||||
| f | false | 343 | 343 | call to c32.~C |
|
||||
| f | false | 344 | 344 | c33 |
|
||||
| f | false | 345 | 345 | call to c33.~C |
|
||||
| f | false | 346 | 346 | c20 |
|
||||
| f | false | 347 | 347 | call to c20.~C |
|
||||
| f | false | 348 | 348 | c31 |
|
||||
| f | false | 350 | 350 | call to c31.~C |
|
||||
| f | false | 351 | 351 | c32 |
|
||||
| f | false | 352 | 352 | call to c32.~C |
|
||||
| f | false | 353 | 353 | c33 |
|
||||
| f | false | 354 | 354 | call to c33.~C |
|
||||
| f | false | 355 | 355 | c20 |
|
||||
| f | false | 356 | 356 | call to c20.~C |
|
||||
| f | false | 357 | 357 | c31 |
|
||||
| f | false | 358 | 358 | call to c31.~C |
|
||||
| f | false | 359 | 359 | c32 |
|
||||
| f | false | 360 | 360 | call to c32.~C |
|
||||
| f | false | 361 | 361 | c20 |
|
||||
| f | false | 362 | 362 | call to c20.~C |
|
||||
| f | false | 363 | 363 | c31 |
|
||||
| f | false | 364 | 364 | call to c31.~C |
|
||||
| f | false | 365 | 365 | c30 |
|
||||
| f | false | 367 | 367 | call to c30.~C |
|
||||
| f | false | 369 | 369 | call to C |
|
||||
| f | false | 373 | 373 | 110 |
|
||||
| f | false | 374 | 374 | initializer for c10 |
|
||||
| f | false | 378 | 378 | call to C |
|
||||
| f | false | 382 | 382 | 111 |
|
||||
| f | false | 383 | 383 | initializer for c11 |
|
||||
| f | true | 192 | 374 | |
|
||||
| f | true | 195 | 226 | |
|
||||
| f | true | 200 | 195 | |
|
||||
| f | true | 201 | 200 | |
|
||||
| f | true | 205 | 343 | |
|
||||
| f | true | 209 | 205 | |
|
||||
| f | true | 210 | 209 | |
|
||||
| f | true | 213 | 201 | |
|
||||
| f | true | 216 | 365 | |
|
||||
| f | true | 220 | 216 | |
|
||||
| f | true | 221 | 220 | |
|
||||
| f | true | 224 | 221 | |
|
||||
| f | true | 226 | 224 | |
|
||||
| f | true | 229 | 262 | |
|
||||
| f | true | 233 | 229 | |
|
||||
| f | true | 234 | 233 | |
|
||||
| f | true | 238 | 271 | |
|
||||
| f | true | 242 | 238 | |
|
||||
| f | true | 243 | 242 | |
|
||||
| f | true | 247 | 353 | |
|
||||
| f | true | 251 | 247 | |
|
||||
| f | true | 252 | 251 | |
|
||||
| f | true | 255 | 234 | |
|
||||
| f | true | 257 | 260 | T |
|
||||
| f | true | 257 | 264 | F |
|
||||
| f | true | 260 | 363 | |
|
||||
| f | true | 262 | 257 | |
|
||||
| f | true | 264 | 243 | |
|
||||
| f | true | 266 | 269 | T |
|
||||
| f | true | 266 | 273 | F |
|
||||
| f | true | 269 | 359 | |
|
||||
| f | true | 271 | 266 | |
|
||||
| f | true | 273 | 252 | |
|
||||
| f | true | 275 | 255 | |
|
||||
| f | true | 278 | 345 | |
|
||||
| f | true | 282 | 278 | |
|
||||
| f | true | 283 | 282 | |
|
||||
| f | true | 286 | 283 | |
|
||||
| f | true | 288 | 286 | |
|
||||
| f | true | 290 | 210 | |
|
||||
| f | true | 292 | 213 | |
|
||||
| f | true | 295 | 337 | |
|
||||
| f | true | 299 | 295 | |
|
||||
| f | true | 300 | 299 | |
|
||||
| f | true | 303 | 300 | |
|
||||
| f | true | 305 | 303 | |
|
||||
| f | true | 308 | 334 | |
|
||||
| f | true | 312 | 308 | |
|
||||
| f | true | 313 | 312 | |
|
||||
| f | true | 316 | 318 | |
|
||||
| f | true | 318 | 313 | |
|
||||
| f | true | 320 | 316 | |
|
||||
| f | true | 322 | 383 | |
|
||||
| f | true | 324 | 332 | |
|
||||
| f | true | 326 | 192 | |
|
||||
| f | true | 328 | 330 | |
|
||||
| f | true | 330 | 181 | |
|
||||
| f | true | 332 | 333 | |
|
||||
| f | true | 333 | 328 | |
|
||||
| f | true | 334 | 336 | |
|
||||
| f | true | 336 | 322 | |
|
||||
| f | true | 337 | 339 | |
|
||||
| f | true | 339 | 320 | |
|
||||
| f | true | 340 | 342 | |
|
||||
| f | true | 342 | 305 | |
|
||||
| f | true | 343 | 344 | |
|
||||
| f | true | 344 | 340 | |
|
||||
| f | true | 345 | 347 | |
|
||||
| f | true | 347 | 290 | |
|
||||
| f | true | 348 | 350 | |
|
||||
| f | true | 350 | 288 | |
|
||||
| f | true | 351 | 352 | |
|
||||
| f | true | 352 | 348 | |
|
||||
| f | false | 349 | 349 | call to c31.~C |
|
||||
| f | false | 350 | 350 | c10 |
|
||||
| f | false | 352 | 352 | call to c10.~C |
|
||||
| f | false | 353 | 353 | c20 |
|
||||
| f | false | 354 | 354 | call to c20.~C |
|
||||
| f | false | 355 | 355 | c31 |
|
||||
| f | false | 356 | 356 | call to c31.~C |
|
||||
| f | false | 357 | 357 | c32 |
|
||||
| f | false | 358 | 358 | call to c32.~C |
|
||||
| f | false | 359 | 359 | c34 |
|
||||
| f | false | 361 | 361 | call to c34.~C |
|
||||
| f | false | 362 | 362 | c22 |
|
||||
| f | false | 364 | 364 | call to c22.~C |
|
||||
| f | false | 365 | 365 | c23 |
|
||||
| f | false | 367 | 367 | call to c23.~C |
|
||||
| f | false | 368 | 368 | c10 |
|
||||
| f | false | 369 | 369 | call to c10.~C |
|
||||
| f | false | 370 | 370 | c11 |
|
||||
| f | false | 371 | 371 | call to c11.~C |
|
||||
| f | true | 176 | 185 | |
|
||||
| f | true | 179 | 285 | |
|
||||
| f | true | 184 | 179 | |
|
||||
| f | true | 185 | 184 | |
|
||||
| f | true | 189 | 219 | |
|
||||
| f | true | 193 | 189 | |
|
||||
| f | true | 194 | 193 | |
|
||||
| f | true | 198 | 334 | |
|
||||
| f | true | 202 | 198 | |
|
||||
| f | true | 203 | 202 | |
|
||||
| f | true | 206 | 194 | |
|
||||
| f | true | 209 | 336 | |
|
||||
| f | true | 213 | 209 | |
|
||||
| f | true | 214 | 213 | |
|
||||
| f | true | 217 | 214 | |
|
||||
| f | true | 219 | 217 | |
|
||||
| f | true | 222 | 250 | |
|
||||
| f | true | 226 | 222 | |
|
||||
| f | true | 227 | 226 | |
|
||||
| f | true | 231 | 259 | |
|
||||
| f | true | 235 | 231 | |
|
||||
| f | true | 236 | 235 | |
|
||||
| f | true | 240 | 344 | |
|
||||
| f | true | 244 | 240 | |
|
||||
| f | true | 245 | 244 | |
|
||||
| f | true | 248 | 227 | |
|
||||
| f | true | 250 | 252 | |
|
||||
| f | true | 252 | 255 | T |
|
||||
| f | true | 252 | 257 | F |
|
||||
| f | true | 255 | 348 | |
|
||||
| f | true | 257 | 236 | |
|
||||
| f | true | 259 | 261 | |
|
||||
| f | true | 261 | 264 | T |
|
||||
| f | true | 261 | 266 | F |
|
||||
| f | true | 264 | 357 | |
|
||||
| f | true | 266 | 245 | |
|
||||
| f | true | 268 | 248 | |
|
||||
| f | true | 271 | 359 | |
|
||||
| f | true | 275 | 271 | |
|
||||
| f | true | 276 | 275 | |
|
||||
| f | true | 279 | 276 | |
|
||||
| f | true | 281 | 279 | |
|
||||
| f | true | 283 | 203 | |
|
||||
| f | true | 285 | 206 | |
|
||||
| f | true | 288 | 362 | |
|
||||
| f | true | 292 | 288 | |
|
||||
| f | true | 293 | 292 | |
|
||||
| f | true | 296 | 293 | |
|
||||
| f | true | 298 | 296 | |
|
||||
| f | true | 301 | 365 | |
|
||||
| f | true | 305 | 301 | |
|
||||
| f | true | 306 | 305 | |
|
||||
| f | true | 309 | 311 | |
|
||||
| f | true | 311 | 306 | |
|
||||
| f | true | 313 | 309 | |
|
||||
| f | true | 315 | 323 | |
|
||||
| f | true | 318 | 326 | |
|
||||
| f | true | 322 | 318 | |
|
||||
| f | true | 323 | 322 | |
|
||||
| f | true | 326 | 370 | |
|
||||
| f | true | 328 | 176 | |
|
||||
| f | true | 330 | 332 | |
|
||||
| f | true | 332 | 298 | |
|
||||
| f | true | 334 | 335 | |
|
||||
| f | true | 335 | 330 | |
|
||||
| f | true | 336 | 338 | |
|
||||
| f | true | 338 | 268 | |
|
||||
| f | true | 339 | 341 | |
|
||||
| f | true | 341 | 281 | |
|
||||
| f | true | 342 | 343 | |
|
||||
| f | true | 343 | 339 | |
|
||||
| f | true | 344 | 345 | |
|
||||
| f | true | 345 | 342 | |
|
||||
| f | true | 346 | 347 | |
|
||||
| f | true | 347 | 309 | |
|
||||
| f | true | 348 | 349 | |
|
||||
| f | true | 349 | 346 | |
|
||||
| f | true | 350 | 352 | |
|
||||
| f | true | 352 | 165 | |
|
||||
| f | true | 353 | 354 | |
|
||||
| f | true | 354 | 351 | |
|
||||
| f | true | 354 | 350 | |
|
||||
| f | true | 355 | 356 | |
|
||||
| f | true | 356 | 328 | |
|
||||
| f | true | 356 | 353 | |
|
||||
| f | true | 357 | 358 | |
|
||||
| f | true | 358 | 355 | |
|
||||
| f | true | 359 | 360 | |
|
||||
| f | true | 360 | 357 | |
|
||||
| f | true | 361 | 362 | |
|
||||
| f | true | 362 | 316 | |
|
||||
| f | true | 363 | 364 | |
|
||||
| f | true | 364 | 361 | |
|
||||
| f | true | 359 | 361 | |
|
||||
| f | true | 361 | 283 | |
|
||||
| f | true | 362 | 364 | |
|
||||
| f | true | 364 | 313 | |
|
||||
| f | true | 365 | 367 | |
|
||||
| f | true | 367 | 275 | |
|
||||
| f | true | 369 | 292 | |
|
||||
| f | true | 373 | 369 | |
|
||||
| f | true | 374 | 373 | |
|
||||
| f | true | 378 | 324 | |
|
||||
| f | true | 382 | 378 | |
|
||||
| f | true | 383 | 382 | |
|
||||
| getClass2 | false | 420 | 420 | getClass2 |
|
||||
| f | true | 367 | 315 | |
|
||||
| f | true | 368 | 369 | |
|
||||
| f | true | 369 | 165 | |
|
||||
| f | true | 370 | 371 | |
|
||||
| f | true | 371 | 368 | |
|
||||
| getClass2 | false | 425 | 425 | getClass2 |
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
| destructors2.cpp:5:7:5:7 | Class2 | 5 | return ... | 3 | 5 | Class2 |
|
||||
| destructors2.cpp:17:9:17:13 | Inner | 17 | return ... | 3 | 17 | Inner |
|
||||
| destructors2.cpp:18:9:18:14 | ~Inner | 18 | return ... | 3 | 18 | ~Inner |
|
||||
| destructors2.cpp:21:10:21:11 | f2 | 24 | return ... | 16 | 27 | c |
|
||||
| destructors2.cpp:21:10:21:11 | f2 | 24 | return ... | 17 | 27 | call to ~Class2 |
|
||||
| destructors2.cpp:21:10:21:11 | f2 | 24 | return ... | 18 | 21 | f2 |
|
||||
| destructors2.cpp:21:10:21:11 | f2 | 24 | return ... | 9 | 27 | c |
|
||||
| destructors2.cpp:21:10:21:11 | f2 | 24 | return ... | 10 | 27 | call to ~Class2 |
|
||||
| destructors2.cpp:21:10:21:11 | f2 | 24 | return ... | 20 | 21 | f2 |
|
||||
| destructors2.cpp:21:10:21:11 | f2 | 27 | return ... | 12 | 27 | inner |
|
||||
| destructors2.cpp:21:10:21:11 | f2 | 27 | return ... | 13 | 27 | call to ~Inner |
|
||||
| destructors2.cpp:21:10:21:11 | f2 | 27 | return ... | 16 | 27 | c |
|
||||
| destructors2.cpp:21:10:21:11 | f2 | 27 | return ... | 17 | 27 | call to ~Class2 |
|
||||
| destructors2.cpp:21:10:21:11 | f2 | 27 | return ... | 18 | 21 | f2 |
|
||||
| destructors2.cpp:21:10:21:11 | f2 | 27 | return ... | 14 | 27 | c |
|
||||
| destructors2.cpp:21:10:21:11 | f2 | 27 | return ... | 15 | 27 | call to ~Class2 |
|
||||
| destructors2.cpp:21:10:21:11 | f2 | 27 | return ... | 20 | 21 | f2 |
|
||||
| destructors.cpp:8:6:8:6 | f | 17 | goto ... | 26 | 21 | c31 |
|
||||
| destructors.cpp:8:6:8:6 | f | 17 | goto ... | 27 | 21 | call to ~C |
|
||||
| destructors.cpp:8:6:8:6 | f | 17 | goto ... | 28 | 26 | c20 |
|
||||
@@ -19,11 +19,11 @@
|
||||
| destructors.cpp:8:6:8:6 | f | 19 | return ... | 35 | 21 | call to ~C |
|
||||
| destructors.cpp:8:6:8:6 | f | 19 | return ... | 36 | 26 | c20 |
|
||||
| destructors.cpp:8:6:8:6 | f | 19 | return ... | 37 | 26 | call to ~C |
|
||||
| destructors.cpp:8:6:8:6 | f | 19 | return ... | 90 | 35 | c10 |
|
||||
| destructors.cpp:8:6:8:6 | f | 19 | return ... | 91 | 35 | call to ~C |
|
||||
| destructors.cpp:8:6:8:6 | f | 19 | return ... | 92 | 8 | f |
|
||||
| destructors.cpp:8:6:8:6 | f | 19 | return ... | 38 | 35 | c10 |
|
||||
| destructors.cpp:8:6:8:6 | f | 19 | return ... | 39 | 35 | call to ~C |
|
||||
| destructors.cpp:8:6:8:6 | f | 19 | return ... | 94 | 8 | f |
|
||||
| destructors.cpp:8:6:8:6 | f | 35 | return ... | 81 | 35 | c11 |
|
||||
| destructors.cpp:8:6:8:6 | f | 35 | return ... | 82 | 35 | call to ~C |
|
||||
| destructors.cpp:8:6:8:6 | f | 35 | return ... | 90 | 35 | c10 |
|
||||
| destructors.cpp:8:6:8:6 | f | 35 | return ... | 91 | 35 | call to ~C |
|
||||
| destructors.cpp:8:6:8:6 | f | 35 | return ... | 92 | 8 | f |
|
||||
| destructors.cpp:8:6:8:6 | f | 35 | return ... | 83 | 35 | c10 |
|
||||
| destructors.cpp:8:6:8:6 | f | 35 | return ... | 84 | 35 | call to ~C |
|
||||
| destructors.cpp:8:6:8:6 | f | 35 | return ... | 94 | 8 | f |
|
||||
|
||||
@@ -17,4 +17,9 @@ void GetUUID() {
|
||||
uuid = __uuidof(s);
|
||||
uuid = __uuidof(0);
|
||||
}
|
||||
|
||||
template <typename Placeholder, typename ...>
|
||||
auto Wrapper = __uuidof(Placeholder);
|
||||
auto inst = Wrapper<S>;
|
||||
|
||||
// semmle-extractor-options: --microsoft
|
||||
|
||||
@@ -12,3 +12,5 @@ uuidofOperators
|
||||
| uuidof.cpp:15:12:15:29 | __uuidof(S) | const _GUID | 01234567-89ab-cdef-0123-456789abcdef |
|
||||
| uuidof.cpp:17:12:17:22 | __uuidof(S) | const _GUID | 01234567-89ab-cdef-0123-456789abcdef |
|
||||
| uuidof.cpp:18:12:18:22 | __uuidof(0) | const _GUID | 00000000-0000-0000-0000-000000000000 |
|
||||
| uuidof.cpp:22:16:22:36 | __uuidof(Placeholder) | const _GUID | |
|
||||
| uuidof.cpp:22:16:22:36 | __uuidof(S) | const _GUID | 01234567-89ab-cdef-0123-456789abcdef |
|
||||
|
||||
@@ -5,6 +5,6 @@ query predicate classUuids(Class cls, string uuid) {
|
||||
}
|
||||
|
||||
query predicate uuidofOperators(UuidofOperator op, string type, string uuid) {
|
||||
uuid = op.getValue() and
|
||||
(if exists(op.getValue()) then uuid = op.getValue() else uuid = "") and
|
||||
type = op.getType().toString()
|
||||
}
|
||||
|
||||
62
cpp/ql/test/library-tests/string_concat/concat.cpp
Normal file
62
cpp/ql/test/library-tests/string_concat/concat.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
// #include <iostream>
|
||||
// #include <string>
|
||||
// #include <stdio.h>
|
||||
// #include <string.h>
|
||||
// #include <sstream>
|
||||
#include "stl.h"
|
||||
|
||||
int sprintf(char *s, const char *format, ...);
|
||||
char *strcat(char * s1, const char * s2);
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
void test1(){
|
||||
string str1 = "Hello";
|
||||
string str2 = "World";
|
||||
string str3 = "!";
|
||||
string str4 = "Concatenation";
|
||||
string str5 = "is";
|
||||
string str6 = "fun";
|
||||
|
||||
// Using the + operator
|
||||
string result1 = str1 + " " + str2 + str3;
|
||||
|
||||
// Using the append() function
|
||||
//----TODO: currently not modeled----
|
||||
// string result2 = str4.append(" ") + str5.append(" ") + str6;
|
||||
|
||||
// Using the insert() function
|
||||
//----TODO: currently not modeled----
|
||||
// string result3 = str1.insert(5, " ") + str2.insert(5, "! ");
|
||||
|
||||
// Using the replace() function
|
||||
//----TODO: currently not modeled----
|
||||
// string result4 = str1.replace(0, 5, "Hi") + str2.replace(0, 5, "There");
|
||||
|
||||
// Using the push_back() function
|
||||
//----TODO: currently not modeled----
|
||||
// string result5;
|
||||
// for (char c : str1) {
|
||||
// result5.push_back(c);
|
||||
// }
|
||||
|
||||
// Using the stream operator
|
||||
string result6;
|
||||
std::stringstream ss;
|
||||
ss << str1 << " " << str2 << str3;
|
||||
}
|
||||
|
||||
|
||||
void test2(char* ucstr) {
|
||||
char str1[20] = "Hello";
|
||||
char str2[20] = "World";
|
||||
char result[40];
|
||||
char *result2;
|
||||
|
||||
// Using sprintf
|
||||
sprintf(result, "%s %s %s", str1, str2, ucstr);
|
||||
|
||||
// Using strcat
|
||||
strcat(str1, ucstr);
|
||||
}
|
||||
644
cpp/ql/test/library-tests/string_concat/stl.h
Normal file
644
cpp/ql/test/library-tests/string_concat/stl.h
Normal file
@@ -0,0 +1,644 @@
|
||||
|
||||
typedef unsigned long size_t;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "type_traits.h"
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<class T> constexpr T&& forward(remove_reference_t<T>& t) noexcept;
|
||||
template<class T> constexpr T&& forward(remove_reference_t<T>&& t) noexcept;
|
||||
}
|
||||
|
||||
// --- iterator ---
|
||||
|
||||
namespace std {
|
||||
struct ptrdiff_t;
|
||||
|
||||
template<class I> struct iterator_traits;
|
||||
|
||||
template <class Category,
|
||||
class value_type,
|
||||
class difference_type = ptrdiff_t,
|
||||
class pointer_type = value_type*,
|
||||
class reference_type = value_type&>
|
||||
struct iterator {
|
||||
typedef Category iterator_category;
|
||||
|
||||
iterator();
|
||||
iterator(iterator<Category, remove_const_t<value_type> > const &other); // non-const -> const conversion constructor
|
||||
|
||||
iterator &operator++();
|
||||
iterator operator++(int);
|
||||
iterator &operator--();
|
||||
iterator operator--(int);
|
||||
bool operator==(iterator other) const;
|
||||
bool operator!=(iterator other) const;
|
||||
reference_type operator*() const;
|
||||
pointer_type operator->() const;
|
||||
iterator operator+(int);
|
||||
iterator operator-(int);
|
||||
iterator &operator+=(int);
|
||||
iterator &operator-=(int);
|
||||
int operator-(iterator);
|
||||
reference_type operator[](int);
|
||||
};
|
||||
|
||||
struct input_iterator_tag {};
|
||||
struct forward_iterator_tag : public input_iterator_tag {};
|
||||
struct bidirectional_iterator_tag : public forward_iterator_tag {};
|
||||
struct random_access_iterator_tag : public bidirectional_iterator_tag {};
|
||||
|
||||
struct output_iterator_tag {};
|
||||
|
||||
template<class Container>
|
||||
class back_insert_iterator {
|
||||
protected:
|
||||
Container* container = nullptr;
|
||||
public:
|
||||
using iterator_category = output_iterator_tag;
|
||||
using value_type = void;
|
||||
using difference_type = ptrdiff_t;
|
||||
using pointer = void;
|
||||
using reference = void;
|
||||
using container_type = Container;
|
||||
constexpr back_insert_iterator() noexcept = default;
|
||||
constexpr explicit back_insert_iterator(Container& x);
|
||||
back_insert_iterator& operator=(const typename Container::value_type& value);
|
||||
back_insert_iterator& operator=(typename Container::value_type&& value);
|
||||
back_insert_iterator& operator*();
|
||||
back_insert_iterator& operator++();
|
||||
back_insert_iterator operator++(int);
|
||||
};
|
||||
|
||||
template<class Container>
|
||||
constexpr back_insert_iterator<Container> back_inserter(Container& x) {
|
||||
return back_insert_iterator<Container>(x);
|
||||
}
|
||||
|
||||
template<class Container>
|
||||
class front_insert_iterator {
|
||||
protected:
|
||||
Container* container = nullptr;
|
||||
public:
|
||||
using iterator_category = output_iterator_tag;
|
||||
using value_type = void;
|
||||
using difference_type = ptrdiff_t;
|
||||
using pointer = void;
|
||||
using reference = void;
|
||||
using container_type = Container;
|
||||
constexpr front_insert_iterator() noexcept = default;
|
||||
constexpr explicit front_insert_iterator(Container& x);
|
||||
constexpr front_insert_iterator& operator=(const typename Container::value_type& value);
|
||||
constexpr front_insert_iterator& operator=(typename Container::value_type&& value);
|
||||
constexpr front_insert_iterator& operator*();
|
||||
constexpr front_insert_iterator& operator++();
|
||||
constexpr front_insert_iterator operator++(int);
|
||||
};
|
||||
template<class Container>
|
||||
constexpr front_insert_iterator<Container> front_inserter(Container& x) {
|
||||
return front_insert_iterator<Container>(x);
|
||||
}
|
||||
}
|
||||
|
||||
// --- string ---
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<class charT> struct char_traits;
|
||||
|
||||
typedef size_t streamsize;
|
||||
|
||||
template <class T> class allocator {
|
||||
public:
|
||||
allocator() throw();
|
||||
typedef size_t size_type;
|
||||
};
|
||||
|
||||
template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
|
||||
class basic_string {
|
||||
public:
|
||||
using value_type = charT;
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
typedef typename Allocator::size_type size_type;
|
||||
static const size_type npos = -1;
|
||||
|
||||
explicit basic_string(const Allocator& a = Allocator());
|
||||
basic_string(const charT* s, const Allocator& a = Allocator());
|
||||
template<class InputIterator> basic_string(InputIterator begin, InputIterator end, const Allocator& a = Allocator());
|
||||
|
||||
const charT* c_str() const;
|
||||
charT* data() noexcept;
|
||||
size_t length() const;
|
||||
|
||||
typedef std::iterator<random_access_iterator_tag, charT> iterator;
|
||||
typedef std::iterator<random_access_iterator_tag, const charT> const_iterator;
|
||||
|
||||
iterator begin();
|
||||
iterator end();
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
const_iterator cbegin() const;
|
||||
const_iterator cend() const;
|
||||
|
||||
void push_back(charT c);
|
||||
|
||||
const charT& front() const;
|
||||
charT& front();
|
||||
const charT& back() const;
|
||||
charT& back();
|
||||
|
||||
const_reference operator[](size_type pos) const;
|
||||
reference operator[](size_type pos);
|
||||
const_reference at(size_type n) const;
|
||||
reference at(size_type n);
|
||||
template<class T> basic_string& operator+=(const T& t);
|
||||
basic_string& operator+=(const charT* s);
|
||||
basic_string& append(const basic_string& str);
|
||||
basic_string& append(const charT* s);
|
||||
basic_string& append(size_type n, charT c);
|
||||
template<class InputIterator> basic_string& append(InputIterator first, InputIterator last);
|
||||
basic_string& assign(const basic_string& str);
|
||||
basic_string& assign(size_type n, charT c);
|
||||
template<class InputIterator> basic_string& assign(InputIterator first, InputIterator last);
|
||||
basic_string& insert(size_type pos, const basic_string& str);
|
||||
basic_string& insert(size_type pos, size_type n, charT c);
|
||||
basic_string& insert(size_type pos, const charT* s);
|
||||
iterator insert(const_iterator p, size_type n, charT c);
|
||||
template<class InputIterator> iterator insert(const_iterator p, InputIterator first, InputIterator last);
|
||||
basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
|
||||
basic_string& replace(size_type pos1, size_type n1, size_type n2, charT c);
|
||||
size_type copy(charT* s, size_type n, size_type pos = 0) const;
|
||||
void clear() noexcept;
|
||||
basic_string substr(size_type pos = 0, size_type n = npos) const;
|
||||
void swap(basic_string& s) noexcept/*(allocator_traits<Allocator>::propagate_on_container_swap::value || allocator_traits<Allocator>::is_always_equal::value)*/;
|
||||
};
|
||||
|
||||
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs);
|
||||
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);
|
||||
|
||||
typedef basic_string<char> string;
|
||||
}
|
||||
|
||||
// --- istring / ostream / stringstream ---
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <class charT, class traits = char_traits<charT> >
|
||||
class basic_istream /*: virtual public basic_ios<charT,traits> - not needed for this test */ {
|
||||
public:
|
||||
using char_type = charT;
|
||||
using int_type = int; //typename traits::int_type;
|
||||
|
||||
basic_istream<charT, traits>& operator>>(int& n);
|
||||
|
||||
int_type get();
|
||||
basic_istream<charT, traits>& get(char_type& c);
|
||||
basic_istream<charT, traits>& get(char_type* s, streamsize n);
|
||||
int_type peek();
|
||||
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:
|
||||
typedef charT char_type;
|
||||
|
||||
basic_ostream<charT, traits>& operator<<(int n);
|
||||
|
||||
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*);
|
||||
template<class charT, class traits, class Allocator> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str);
|
||||
|
||||
template<class charT, class traits = char_traits<charT>>
|
||||
class basic_iostream : public basic_istream<charT, traits>, public basic_ostream<charT, traits> {
|
||||
public:
|
||||
};
|
||||
|
||||
template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
|
||||
class basic_stringstream : public basic_iostream<charT, traits> {
|
||||
public:
|
||||
explicit basic_stringstream(/*ios_base::openmode which = ios_base::out|ios_base::in - not needed for this test*/);
|
||||
explicit basic_stringstream( const basic_string<charT, traits, Allocator>& str/*, ios_base::openmode which = ios_base::out | ios_base::in*/);
|
||||
basic_stringstream(const basic_stringstream& rhs) = delete;
|
||||
basic_stringstream(basic_stringstream&& rhs);
|
||||
basic_stringstream& operator=(const basic_stringstream& rhs) = delete;
|
||||
basic_stringstream& operator=(basic_stringstream&& rhs);
|
||||
|
||||
void swap(basic_stringstream& rhs);
|
||||
|
||||
basic_string<charT, traits, Allocator> str() const;
|
||||
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>;
|
||||
}
|
||||
|
||||
// --- vector ---
|
||||
|
||||
namespace std {
|
||||
template<class T, class Allocator = allocator<T>>
|
||||
class vector {
|
||||
public:
|
||||
using value_type = T;
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
using size_type = unsigned int;
|
||||
using iterator = std::iterator<random_access_iterator_tag, T>;
|
||||
using const_iterator = std::iterator<random_access_iterator_tag, const T>;
|
||||
|
||||
vector() noexcept(noexcept(Allocator())) : vector(Allocator()) { }
|
||||
explicit vector(const Allocator&) noexcept;
|
||||
explicit vector(size_type n, const Allocator& = Allocator());
|
||||
vector(size_type n, const T& value, const Allocator& = Allocator());
|
||||
template<class InputIterator, class IteratorCategory = typename InputIterator::iterator_category> vector(InputIterator first, InputIterator last, const Allocator& = Allocator());
|
||||
// use of `iterator_category` makes sure InputIterator is (probably) an iterator, and not an `int` or
|
||||
// similar that should match a different overload (SFINAE).
|
||||
~vector();
|
||||
|
||||
vector& operator=(const vector& x);
|
||||
vector& operator=(vector&& x) noexcept/*(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value)*/;
|
||||
template<class InputIterator, class IteratorCategory = typename InputIterator::iterator_category> void assign(InputIterator first, InputIterator last);
|
||||
// use of `iterator_category` makes sure InputIterator is (probably) an iterator, and not an `int` or
|
||||
// similar that should match a different overload (SFINAE).
|
||||
void assign(size_type n, const T& u);
|
||||
|
||||
iterator begin() noexcept;
|
||||
const_iterator begin() const noexcept;
|
||||
iterator end() noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
|
||||
size_type size() const noexcept;
|
||||
|
||||
reference operator[](size_type n);
|
||||
const_reference operator[](size_type n) const;
|
||||
const_reference at(size_type n) const;
|
||||
reference at(size_type n);
|
||||
reference front();
|
||||
const_reference front() const;
|
||||
reference back();
|
||||
const_reference back() const;
|
||||
|
||||
T* data() noexcept;
|
||||
const T* data() const noexcept;
|
||||
|
||||
void push_back(const T& x);
|
||||
void push_back(T&& x);
|
||||
|
||||
iterator insert(const_iterator position, const T& x);
|
||||
iterator insert(const_iterator position, T&& x);
|
||||
iterator insert(const_iterator position, size_type n, const T& x);
|
||||
template<class InputIterator> iterator insert(const_iterator position, InputIterator first, InputIterator last);
|
||||
|
||||
template <class... Args> iterator emplace (const_iterator position, Args&&... args);
|
||||
template <class... Args> void emplace_back (Args&&... args);
|
||||
|
||||
void swap(vector&) noexcept/*(allocator_traits<Allocator>::propagate_on_container_swap::value || allocator_traits<Allocator>::is_always_equal::value)*/;
|
||||
|
||||
void clear() noexcept;
|
||||
};
|
||||
}
|
||||
|
||||
// --- make_shared / make_unique ---
|
||||
|
||||
namespace std {
|
||||
template<typename T>
|
||||
class shared_ptr {
|
||||
public:
|
||||
shared_ptr() noexcept;
|
||||
explicit shared_ptr(T*);
|
||||
shared_ptr(const shared_ptr&) noexcept;
|
||||
template<class U> shared_ptr(const shared_ptr<U>&) noexcept;
|
||||
template<class U> shared_ptr(shared_ptr<U>&&) noexcept;
|
||||
|
||||
shared_ptr<T>& operator=(const shared_ptr<T>&) noexcept;
|
||||
shared_ptr<T>& operator=(shared_ptr<T>&&) noexcept;
|
||||
|
||||
T& operator*() const noexcept;
|
||||
T* operator->() const noexcept;
|
||||
|
||||
T* get() const noexcept;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class unique_ptr {
|
||||
public:
|
||||
constexpr unique_ptr() noexcept;
|
||||
explicit unique_ptr(T*) noexcept;
|
||||
unique_ptr(unique_ptr<T>&&) noexcept;
|
||||
|
||||
unique_ptr<T>& operator=(unique_ptr<T>&&) noexcept;
|
||||
|
||||
T& operator*() const;
|
||||
T* operator->() const noexcept;
|
||||
|
||||
T* get() const noexcept;
|
||||
};
|
||||
|
||||
template<typename T, class... Args> unique_ptr<T> make_unique(Args&&...);
|
||||
|
||||
template<typename T, class... Args> shared_ptr<T> make_shared(Args&&...);
|
||||
}
|
||||
|
||||
// --- pair ---
|
||||
|
||||
namespace std {
|
||||
template <class T1, class T2>
|
||||
struct pair {
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
|
||||
T1 first;
|
||||
T2 second;
|
||||
pair();
|
||||
pair(const T1& x, const T2& y) : first(x), second(y) {};
|
||||
template<class U, class V> pair(const pair<U, V> &p);
|
||||
|
||||
void swap(pair& p) /*noexcept(...)*/;
|
||||
};
|
||||
|
||||
template<class T1, class T2> constexpr pair<decay_t<T1>, decay_t<T2>> make_pair(T1&& x, T2&& y) {
|
||||
return pair<decay_t<T1>, decay_t<T2>>(std::forward<T1>(x), std::forward<T2>(y));
|
||||
}
|
||||
}
|
||||
|
||||
// --- map ---
|
||||
|
||||
namespace std {
|
||||
template<class T = void> struct less;
|
||||
|
||||
template<class Key, class T, class Compare = less<Key>, class Allocator = allocator<pair<const Key, T>>>
|
||||
class map {
|
||||
public:
|
||||
using key_type = Key;
|
||||
using mapped_type = T;
|
||||
using value_type = pair<const Key, T>;
|
||||
using iterator = std::iterator<random_access_iterator_tag, value_type >;
|
||||
using const_iterator = std::iterator<random_access_iterator_tag, const value_type >;
|
||||
|
||||
map() /*: map(Compare()) { }*/;
|
||||
map(const map& x);
|
||||
map(map&& x);
|
||||
~map();
|
||||
|
||||
map& operator=(const map& x);
|
||||
map& operator=(map&& x) /*noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_move_assignable_v<Compare>)*/;
|
||||
|
||||
iterator begin() noexcept;
|
||||
const_iterator begin() const noexcept;
|
||||
iterator end() noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
|
||||
T& operator[](const key_type& x);
|
||||
T& operator[](key_type&& x);
|
||||
T& at(const key_type& x);
|
||||
const T& at(const key_type& x) const;
|
||||
|
||||
template<class... Args> pair<iterator, bool> emplace(Args&&... args);
|
||||
template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
|
||||
|
||||
pair<iterator, bool> insert(const value_type& x);
|
||||
pair<iterator, bool> insert(value_type&& x);
|
||||
iterator insert(const_iterator position, const value_type& x);
|
||||
iterator insert(const_iterator position, value_type&& x);
|
||||
|
||||
template<class... Args> pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
|
||||
template<class... Args> pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
|
||||
template<class... Args> iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
|
||||
template<class... Args> iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
|
||||
template<class M> pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
|
||||
template<class M> pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
|
||||
template<class M> iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
|
||||
template<class M> iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
|
||||
|
||||
iterator erase(iterator position);
|
||||
iterator erase(const_iterator position);
|
||||
iterator erase(const_iterator first, const_iterator last);
|
||||
void swap(map&) /*noexcept(/*==allocator_traits<Allocator>::is_always_equal::value && is_nothrow_swappable_v<Compare>)*/;
|
||||
void clear() noexcept;
|
||||
|
||||
template<class C2> void merge(map<Key, T, C2, Allocator>& source);
|
||||
template<class C2> void merge(map<Key, T, C2, Allocator>&& source);
|
||||
|
||||
iterator find(const key_type& x);
|
||||
const_iterator find(const key_type& x) const;
|
||||
|
||||
iterator lower_bound(const key_type& x);
|
||||
const_iterator lower_bound(const key_type& x) const;
|
||||
iterator upper_bound(const key_type& x);
|
||||
const_iterator upper_bound(const key_type& x) const;
|
||||
|
||||
pair<iterator, iterator> equal_range(const key_type& x);
|
||||
pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
|
||||
};
|
||||
|
||||
template<class T> struct hash;
|
||||
template<class T = void> struct equal_to;
|
||||
|
||||
template<class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>>
|
||||
class unordered_map {
|
||||
public:
|
||||
using key_type = Key;
|
||||
using mapped_type = T;
|
||||
using value_type = pair<const Key, T>;
|
||||
using iterator = std::iterator<random_access_iterator_tag, value_type >;
|
||||
using const_iterator = std::iterator<random_access_iterator_tag, const value_type >;
|
||||
|
||||
unordered_map();
|
||||
unordered_map(const unordered_map&);
|
||||
unordered_map(unordered_map&&);
|
||||
~unordered_map();
|
||||
|
||||
unordered_map& operator=(const unordered_map&);
|
||||
unordered_map& operator=(unordered_map&&) /*noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_move_assignable_v<Hash> && is_nothrow_move_assignable_v<Pred>)*/;
|
||||
|
||||
iterator begin() noexcept;
|
||||
const_iterator begin() const noexcept;
|
||||
iterator end() noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
|
||||
mapped_type& operator[](const key_type& k);
|
||||
mapped_type& operator[](key_type&& k);
|
||||
mapped_type& at(const key_type& k);
|
||||
const mapped_type& at(const key_type& k) const;
|
||||
|
||||
template<class... Args> pair<iterator, bool> emplace(Args&&... args);
|
||||
template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
|
||||
|
||||
pair<iterator, bool> insert(const value_type& obj);
|
||||
pair<iterator, bool> insert(value_type&& obj);
|
||||
iterator insert(const_iterator hint, const value_type& obj);
|
||||
iterator insert(const_iterator hint, value_type&& obj);
|
||||
|
||||
template<class... Args> pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
|
||||
template<class... Args> pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
|
||||
template<class... Args> iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
|
||||
template<class... Args> iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
|
||||
template<class M> pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
|
||||
template<class M> pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
|
||||
template<class M> iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
|
||||
template<class M> iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
|
||||
|
||||
iterator erase(iterator position);
|
||||
iterator erase(const_iterator position);
|
||||
iterator erase(const_iterator first, const_iterator last);
|
||||
void swap(unordered_map&) /*noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_swappable_v<Hash> && is_nothrow_swappable_v<Pred>)*/;
|
||||
void clear() noexcept;
|
||||
|
||||
template<class H2, class P2> void merge(unordered_map<Key, T, H2, P2, Allocator>& source);
|
||||
template<class H2, class P2> void merge(unordered_map<Key, T, H2, P2, Allocator>&& source);
|
||||
|
||||
iterator find(const key_type& k);
|
||||
const_iterator find(const key_type& k) const;
|
||||
|
||||
pair<iterator, iterator> equal_range(const key_type& k);
|
||||
pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
|
||||
};
|
||||
};
|
||||
|
||||
// --- set ---
|
||||
|
||||
namespace std {
|
||||
template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>
|
||||
class set {
|
||||
public:
|
||||
using key_type = Key;
|
||||
using value_type = Key;
|
||||
using size_type = size_t;
|
||||
using allocator_type = Allocator;
|
||||
using iterator = std::iterator<random_access_iterator_tag, value_type >;
|
||||
using const_iterator = std::iterator<random_access_iterator_tag, const value_type >;
|
||||
|
||||
set() /*: set(Compare())*/ { }
|
||||
set(const set& x);
|
||||
set(set&& x);
|
||||
template<class InputIterator> set(InputIterator first, InputIterator last/*, const Compare& comp = Compare(), const Allocator& = Allocator()*/);
|
||||
~set();
|
||||
|
||||
set& operator=(const set& x);
|
||||
set& operator=(set&& x) noexcept/*(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_move_assignable_v<Compare>)*/;
|
||||
|
||||
iterator begin() noexcept;
|
||||
const_iterator begin() const noexcept;
|
||||
iterator end() noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
|
||||
template<class... Args> pair<iterator, bool> emplace(Args&&... args);
|
||||
template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
|
||||
pair<iterator,bool> insert(const value_type& x);
|
||||
pair<iterator,bool> insert(value_type&& x);
|
||||
iterator insert(const_iterator position, const value_type& x);
|
||||
iterator insert(const_iterator position, value_type&& x);
|
||||
template<class InputIterator> void insert(InputIterator first, InputIterator last);
|
||||
|
||||
iterator erase(iterator position);
|
||||
iterator erase(const_iterator position);
|
||||
iterator erase(const_iterator first, const_iterator last);
|
||||
void swap(set&) noexcept/*(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_swappable_v<Compare>)*/;
|
||||
void clear() noexcept;
|
||||
|
||||
template<class C2> void merge(set<Key, C2, Allocator>& source);
|
||||
template<class C2> void merge(set<Key, C2, Allocator>&& source);
|
||||
|
||||
iterator find(const key_type& x);
|
||||
const_iterator find(const key_type& x) const;
|
||||
|
||||
iterator lower_bound(const key_type& x);
|
||||
const_iterator lower_bound(const key_type& x) const;
|
||||
iterator upper_bound(const key_type& x);
|
||||
const_iterator upper_bound(const key_type& x) const;
|
||||
pair<iterator, iterator> equal_range(const key_type& x);
|
||||
pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
|
||||
};
|
||||
|
||||
template<class Key, class Hash = hash<Key>, class Pred = equal_to<Key>, class Allocator = allocator<Key>>
|
||||
class unordered_set {
|
||||
public:
|
||||
using key_type = Key;
|
||||
using value_type = Key;
|
||||
using hasher = Hash;
|
||||
using key_equal = Pred;
|
||||
using allocator_type = Allocator;
|
||||
using size_type = size_t;
|
||||
using iterator = std::iterator<random_access_iterator_tag, value_type >;
|
||||
using const_iterator = std::iterator<random_access_iterator_tag, const value_type >;
|
||||
|
||||
unordered_set();
|
||||
unordered_set(const unordered_set&);
|
||||
unordered_set(unordered_set&&);
|
||||
template<class InputIterator> unordered_set(InputIterator f, InputIterator l, size_type n = 0/*, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()*/);
|
||||
~unordered_set();
|
||||
|
||||
unordered_set& operator=(const unordered_set&);
|
||||
unordered_set& operator=(unordered_set&&) noexcept/*(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_move_assignable_v<Hash> && is_nothrow_move_assignable_v<Pred>)*/;
|
||||
|
||||
iterator begin() noexcept;
|
||||
const_iterator begin() const noexcept;
|
||||
iterator end() noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
|
||||
template<class... Args> pair<iterator, bool> emplace(Args&&... args);
|
||||
template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
|
||||
pair<iterator, bool> insert(const value_type& obj);
|
||||
pair<iterator, bool> insert(value_type&& obj);
|
||||
iterator insert(const_iterator hint, const value_type& obj);
|
||||
iterator insert(const_iterator hint, value_type&& obj);
|
||||
template<class InputIterator> void insert(InputIterator first, InputIterator last);
|
||||
|
||||
iterator erase(iterator position);
|
||||
iterator erase(const_iterator position);
|
||||
iterator erase(const_iterator first, const_iterator last);
|
||||
void swap(unordered_set&) noexcept/*(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_swappable_v<Hash> && is_nothrow_swappable_v<Pred>)*/;
|
||||
void clear() noexcept;
|
||||
|
||||
template<class H2, class P2> void merge(unordered_set<Key, H2, P2, Allocator>& source);
|
||||
template<class H2, class P2> void merge(unordered_set<Key, H2, P2, Allocator>&& source);
|
||||
|
||||
iterator find(const key_type& k);
|
||||
const_iterator find(const key_type& k) const;
|
||||
pair<iterator, iterator> equal_range(const key_type& k);
|
||||
pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
|
||||
};
|
||||
}
|
||||
19
cpp/ql/test/library-tests/string_concat/strconcat.expected
Normal file
19
cpp/ql/test/library-tests/string_concat/strconcat.expected
Normal file
@@ -0,0 +1,19 @@
|
||||
| concat.cpp:23:27:23:27 | call to operator+ | concat.cpp:23:22:23:25 | str1 | concat.cpp:23:22:23:31 | call to operator+ |
|
||||
| concat.cpp:23:27:23:27 | call to operator+ | concat.cpp:23:22:23:25 | str1 | concat.cpp:23:27:23:27 | call to operator+ |
|
||||
| concat.cpp:23:27:23:27 | call to operator+ | concat.cpp:23:29:23:31 | | concat.cpp:23:22:23:31 | call to operator+ |
|
||||
| concat.cpp:23:27:23:27 | call to operator+ | concat.cpp:23:29:23:31 | | concat.cpp:23:27:23:27 | call to operator+ |
|
||||
| concat.cpp:23:33:23:33 | call to operator+ | concat.cpp:23:35:23:38 | str2 | concat.cpp:23:22:23:38 | call to operator+ |
|
||||
| concat.cpp:23:33:23:33 | call to operator+ | concat.cpp:23:35:23:38 | str2 | concat.cpp:23:33:23:33 | call to operator+ |
|
||||
| concat.cpp:23:40:23:40 | call to operator+ | concat.cpp:23:42:23:45 | str3 | concat.cpp:23:40:23:40 | call to operator+ |
|
||||
| concat.cpp:47:8:47:8 | call to operator<< | concat.cpp:47:11:47:14 | str1 | concat.cpp:47:8:47:17 | call to operator<< |
|
||||
| concat.cpp:47:16:47:16 | call to operator<< | concat.cpp:47:19:47:21 | | concat.cpp:47:16:47:24 | call to operator<< |
|
||||
| concat.cpp:47:23:47:23 | call to operator<< | concat.cpp:47:26:47:29 | str2 | concat.cpp:47:23:47:32 | call to operator<< |
|
||||
| concat.cpp:47:31:47:31 | call to operator<< | concat.cpp:47:34:47:37 | str3 | concat.cpp:47:31:47:38 | call to operator<< |
|
||||
| concat.cpp:58:5:58:11 | call to sprintf | concat.cpp:58:21:58:30 | %s %s %s | concat.cpp:58:13:58:18 | sprintf output argument |
|
||||
| concat.cpp:58:5:58:11 | call to sprintf | concat.cpp:58:33:58:36 | str1 | concat.cpp:58:13:58:18 | sprintf output argument |
|
||||
| concat.cpp:58:5:58:11 | call to sprintf | concat.cpp:58:39:58:42 | str2 | concat.cpp:58:13:58:18 | sprintf output argument |
|
||||
| concat.cpp:58:5:58:11 | call to sprintf | concat.cpp:58:45:58:49 | ucstr | concat.cpp:58:13:58:18 | sprintf output argument |
|
||||
| concat.cpp:61:5:61:10 | call to strcat | concat.cpp:61:12:61:15 | str1 | concat.cpp:61:5:61:10 | call to strcat |
|
||||
| concat.cpp:61:5:61:10 | call to strcat | concat.cpp:61:12:61:15 | str1 | concat.cpp:61:12:61:15 | strcat output argument |
|
||||
| concat.cpp:61:5:61:10 | call to strcat | concat.cpp:61:18:61:22 | ucstr | concat.cpp:61:5:61:10 | call to strcat |
|
||||
| concat.cpp:61:5:61:10 | call to strcat | concat.cpp:61:18:61:22 | ucstr | concat.cpp:61:12:61:15 | strcat output argument |
|
||||
10
cpp/ql/test/library-tests/string_concat/strconcat.ql
Normal file
10
cpp/ql/test/library-tests/string_concat/strconcat.ql
Normal file
@@ -0,0 +1,10 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.commons.StringConcatenation
|
||||
import semmle.code.cpp.dataflow.new.DataFlow
|
||||
|
||||
from StringConcatenation s, Expr op, DataFlow::Node res
|
||||
where
|
||||
s.getLocation().getFile().getBaseName() = "concat.cpp" and
|
||||
op = s.getAnOperand() and
|
||||
res = s.getResultNode()
|
||||
select s, op, res
|
||||
35
cpp/ql/test/library-tests/string_concat/type_traits.h
Normal file
35
cpp/ql/test/library-tests/string_concat/type_traits.h
Normal file
@@ -0,0 +1,35 @@
|
||||
template<class T>
|
||||
struct remove_const { typedef T type; };
|
||||
|
||||
template<class T>
|
||||
struct remove_const<const T> { typedef T type; };
|
||||
|
||||
// `remove_const_t<T>` removes any `const` specifier from `T`
|
||||
template<class T>
|
||||
using remove_const_t = typename remove_const<T>::type;
|
||||
|
||||
template<class T>
|
||||
struct remove_reference { typedef T type; };
|
||||
|
||||
template<class T>
|
||||
struct remove_reference<T &> { typedef T type; };
|
||||
|
||||
template<class T>
|
||||
struct remove_reference<T &&> { typedef T type; };
|
||||
|
||||
// `remove_reference_t<T>` removes any `&` from `T`
|
||||
template<class T>
|
||||
using remove_reference_t = typename remove_reference<T>::type;
|
||||
|
||||
template<class T>
|
||||
struct decay_impl {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T, size_t t_size>
|
||||
struct decay_impl<T[t_size]> {
|
||||
typedef T* type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
using decay_t = typename decay_impl<remove_reference_t<T>>::type;
|
||||
@@ -99,3 +99,4 @@ uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
lambdaCallEnclosingCallableMismatch
|
||||
|
||||
@@ -42,3 +42,4 @@ uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
lambdaCallEnclosingCallableMismatch
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
| test_free.cpp:216:10:216:10 | a |
|
||||
| test_free.cpp:220:10:220:10 | a |
|
||||
| test_free.cpp:227:24:227:45 | memory_descriptor_list |
|
||||
| test_free.cpp:228:16:228:37 | memory_descriptor_list |
|
||||
| test_free.cpp:233:14:233:15 | * ... |
|
||||
| test_free.cpp:239:14:239:15 | * ... |
|
||||
| test_free.cpp:245:10:245:11 | * ... |
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "test.H"
|
||||
#include "test.xpm"
|
||||
#include "test2.c"
|
||||
#include "test.H" // GOOD
|
||||
#include "test.xpm" // GOOD
|
||||
#include "test2.c" // BAD
|
||||
#include "test.def" // GOOD
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,9 @@
|
||||
class Type extends @type {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from Type t, int k, int kind, string name
|
||||
where
|
||||
types(t, k, name) and
|
||||
if k = 34 then kind = 15 else kind = k
|
||||
select t, kind, name
|
||||
@@ -0,0 +1,3 @@
|
||||
description: Remove support for inline arrays.
|
||||
compatibility: backwards
|
||||
types.rel: run types.qlo
|
||||
@@ -650,12 +650,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
|
||||
}
|
||||
|
||||
private bool RestoreProject(string project, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> assets, string? pathToNugetConfig = null) =>
|
||||
dotnet.RestoreProjectToDirectory(project, packageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching, out assets, pathToNugetConfig);
|
||||
|
||||
private bool RestoreSolution(string solution, out IEnumerable<string> projects, out IEnumerable<string> assets) =>
|
||||
dotnet.RestoreSolutionToDirectory(solution, packageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching: true, out projects, out assets);
|
||||
|
||||
/// <summary>
|
||||
/// Executes `dotnet restore` on all solution files in solutions.
|
||||
/// As opposed to RestoreProjects this is not run in parallel using PLINQ
|
||||
@@ -670,7 +664,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
var assetFiles = new List<string>();
|
||||
var projects = solutions.SelectMany(solution =>
|
||||
{
|
||||
RestoreSolution(solution, out var restoredProjects, out var a);
|
||||
dotnet.RestoreSolutionToDirectory(solution, packageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching: true, out var restoredProjects, out var a);
|
||||
assetFiles.AddRange(a);
|
||||
return restoredProjects;
|
||||
});
|
||||
@@ -689,7 +683,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
var assetFiles = new List<string>();
|
||||
Parallel.ForEach(projects, new ParallelOptions { MaxDegreeOfParallelism = options.Threads }, project =>
|
||||
{
|
||||
RestoreProject(project, forceDotnetRefAssemblyFetching: true, out var a);
|
||||
dotnet.RestoreProjectToDirectory(project, packageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching: true, out var a, out var _);
|
||||
assetFiles.AddRange(a);
|
||||
});
|
||||
assets = assetFiles;
|
||||
@@ -736,11 +730,21 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
return;
|
||||
}
|
||||
|
||||
dotnet.RestoreProjectToDirectory(tempDir.DirInfo.FullName, missingPackageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching: false, out var _, pathToNugetConfig: nugetConfig);
|
||||
// TODO: the restore might fail, we could retry with a prerelease (*-* instead of *) version of the package.
|
||||
success = dotnet.RestoreProjectToDirectory(tempDir.DirInfo.FullName, missingPackageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching: false, out var _, out var outputLines, pathToNugetConfig: nugetConfig);
|
||||
if (!success)
|
||||
{
|
||||
progressMonitor.FailedToRestoreNugetPackage(package);
|
||||
if (outputLines?.Any(s => s.Contains("NU1301")) == true)
|
||||
{
|
||||
// Restore could not be completed because the listed source is unavailable. Try without the nuget.config:
|
||||
success = dotnet.RestoreProjectToDirectory(tempDir.DirInfo.FullName, missingPackageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching: false, out var _, out var _, pathToNugetConfig: null, force: true);
|
||||
}
|
||||
|
||||
// TODO: the restore might fail, we could retry with a prerelease (*-* instead of *) version of the package.
|
||||
|
||||
if (!success)
|
||||
{
|
||||
progressMonitor.FailedToRestoreNugetPackage(package);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
private static IEnumerable<string> GetRestoredProjects(IEnumerable<string> lines) =>
|
||||
GetFirstGroupOnMatch(RestoredProjectRegex(), lines);
|
||||
|
||||
public bool RestoreProjectToDirectory(string projectFile, string packageDirectory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> assets, string? pathToNugetConfig = null)
|
||||
public bool RestoreProjectToDirectory(string projectFile, string packageDirectory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> assets, out IList<string> outputLines, string? pathToNugetConfig = null, bool force = false)
|
||||
{
|
||||
var args = GetRestoreArgs(projectFile, packageDirectory, forceDotnetRefAssemblyFetching);
|
||||
if (pathToNugetConfig != null)
|
||||
@@ -80,8 +80,13 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
args += $" --configfile \"{pathToNugetConfig}\"";
|
||||
}
|
||||
|
||||
var success = dotnetCliInvoker.RunCommand(args, out var output);
|
||||
assets = success ? GetAssetsFilePaths(output) : Array.Empty<string>();
|
||||
if (force)
|
||||
{
|
||||
args += " --force";
|
||||
}
|
||||
|
||||
var success = dotnetCliInvoker.RunCommand(args, out outputLines);
|
||||
assets = success ? GetAssetsFilePaths(outputLines) : Array.Empty<string>();
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,16 +74,18 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
includeByDefault)
|
||||
});
|
||||
|
||||
// Move included pathfilters to the front of the list:
|
||||
pathFilters.Sort((pf1, pf2) => -1 * pf1.Include.CompareTo(pf2.Include));
|
||||
return unfilteredResult.Where(f =>
|
||||
{
|
||||
var include = f.FileInclusion.Include;
|
||||
foreach (var pathFilter in pathFilters)
|
||||
// LGTM_INDEX_FILTERS is a prioritized list, where later filters take
|
||||
// priority over earlier ones.
|
||||
for (int i = pathFilters.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var pathFilter = pathFilters[i];
|
||||
if (pathFilter.Regex.IsMatch(f.FileInclusion.Path))
|
||||
{
|
||||
include = pathFilter.Include;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal interface IDotNet
|
||||
{
|
||||
bool RestoreProjectToDirectory(string project, string directory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> assets, string? pathToNugetConfig = null);
|
||||
bool RestoreProjectToDirectory(string project, string directory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> assets, out IList<string> outputLines, string? pathToNugetConfig = null, bool force = false);
|
||||
bool RestoreSolutionToDirectory(string solutionFile, string packageDirectory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> projects, out IEnumerable<string> assets);
|
||||
bool New(string folder);
|
||||
bool AddPackage(string folder, string package);
|
||||
|
||||
@@ -43,6 +43,9 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
|
||||
public sealed override Microsoft.CodeAnalysis.Location? ReportingLocation => base.ReportingLocation;
|
||||
|
||||
private static bool IsArray(ITypeSymbol symbol) =>
|
||||
symbol.TypeKind == Microsoft.CodeAnalysis.TypeKind.Array || symbol.IsInlineArray();
|
||||
|
||||
private static ExprKind GetKind(Context cx, ExpressionSyntax qualifier)
|
||||
{
|
||||
var qualifierType = cx.GetType(qualifier);
|
||||
@@ -59,7 +62,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
|
||||
return IsDynamic(cx, qualifier)
|
||||
? ExprKind.DYNAMIC_ELEMENT_ACCESS
|
||||
: qualifierType.Symbol.TypeKind == Microsoft.CodeAnalysis.TypeKind.Array
|
||||
: IsArray(qualifierType.Symbol)
|
||||
? ExprKind.ARRAY_ACCESS
|
||||
: ExprKind.INDEXER_ACCESS;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,12 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public IMethodSymbol SourceDeclaration => Symbol.OriginalDefinition;
|
||||
|
||||
public override Microsoft.CodeAnalysis.Location ReportingLocation => Symbol.GetSymbolLocation();
|
||||
public override Microsoft.CodeAnalysis.Location ReportingLocation =>
|
||||
IsCompilerGeneratedDelegate()
|
||||
? Symbol.ContainingType.GetSymbolLocation()
|
||||
: Symbol.GetSymbolLocation();
|
||||
|
||||
public override bool NeedsPopulation => base.NeedsPopulation || IsCompilerGeneratedDelegate();
|
||||
|
||||
public override void Populate(TextWriter trapFile)
|
||||
{
|
||||
@@ -47,6 +52,13 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
ExtractCompilerGenerated(trapFile);
|
||||
}
|
||||
|
||||
private bool IsCompilerGeneratedDelegate() =>
|
||||
// Lambdas with parameter defaults or a `params` parameter are implemented
|
||||
// using compiler generated delegate types.
|
||||
Symbol.MethodKind == MethodKind.DelegateInvoke &&
|
||||
Symbol.ContainingType is INamedTypeSymbol nt &&
|
||||
nt.IsImplicitlyDeclared;
|
||||
|
||||
public static new OrdinaryMethod Create(Context cx, IMethodSymbol method)
|
||||
{
|
||||
if (method.MethodKind == MethodKind.ReducedExtension)
|
||||
|
||||
@@ -52,9 +52,15 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
case TypeKind.Class: return Kinds.TypeKind.CLASS;
|
||||
case TypeKind.Struct:
|
||||
return ((INamedTypeSymbol)Symbol).IsTupleType && !constructUnderlyingTupleType
|
||||
? Kinds.TypeKind.TUPLE
|
||||
: Kinds.TypeKind.STRUCT;
|
||||
{
|
||||
if (((INamedTypeSymbol)Symbol).IsTupleType && !constructUnderlyingTupleType)
|
||||
{
|
||||
return Kinds.TypeKind.TUPLE;
|
||||
}
|
||||
return Symbol.IsInlineArray()
|
||||
? Kinds.TypeKind.INLINE_ARRAY
|
||||
: Kinds.TypeKind.STRUCT;
|
||||
}
|
||||
case TypeKind.Interface: return Kinds.TypeKind.INTERFACE;
|
||||
case TypeKind.Array: return Kinds.TypeKind.ARRAY;
|
||||
case TypeKind.Enum: return Kinds.TypeKind.ENUM;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
namespace Semmle.Extraction.Kinds // lgtm[cs/similar-file]
|
||||
namespace Semmle.Extraction.Kinds
|
||||
{
|
||||
/// <summary>
|
||||
/// This enum has been auto-generated from the C# DB scheme - do not edit.
|
||||
/// Auto-generate command: `genkindenum.pl type`
|
||||
/// </summary>
|
||||
public enum TypeKind
|
||||
{
|
||||
@@ -35,6 +36,7 @@ namespace Semmle.Extraction.Kinds // lgtm[cs/similar-file]
|
||||
ARGLIST = 30,
|
||||
UNKNOWN = 31,
|
||||
TUPLE = 32,
|
||||
FUNCTION_POINTER = 33
|
||||
FUNCTION_POINTER = 33,
|
||||
INLINE_ARRAY = 34,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -524,6 +524,17 @@ namespace Semmle.Extraction.CSharp
|
||||
public static bool IsUnboundReadOnlySpan(this ITypeSymbol type) =>
|
||||
type.ToString() == "System.ReadOnlySpan<T>";
|
||||
|
||||
public static bool IsInlineArray(this ITypeSymbol type)
|
||||
{
|
||||
var attributes = type.GetAttributes();
|
||||
var isInline = attributes.Any(attribute =>
|
||||
attribute.AttributeClass is INamedTypeSymbol nt &&
|
||||
nt.Name == "InlineArrayAttribute" &&
|
||||
nt.ContainingNamespace.ToString() == "System.Runtime.CompilerServices"
|
||||
);
|
||||
return isInline;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds if this type is of the form <code>System.ReadOnlySpan<byte></code>.
|
||||
/// </summary>
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace Semmle.Extraction.Tests
|
||||
var dotnet = MakeDotnet(dotnetCliInvoker);
|
||||
|
||||
// Execute
|
||||
dotnet.RestoreProjectToDirectory("myproject.csproj", "mypackages", false, out var assets);
|
||||
dotnet.RestoreProjectToDirectory("myproject.csproj", "mypackages", false, out var assets, out var _);
|
||||
|
||||
// Verify
|
||||
var lastArgs = dotnetCliInvoker.GetLastArgs();
|
||||
@@ -116,7 +116,7 @@ namespace Semmle.Extraction.Tests
|
||||
var dotnet = MakeDotnet(dotnetCliInvoker);
|
||||
|
||||
// Execute
|
||||
dotnet.RestoreProjectToDirectory("myproject.csproj", "mypackages", false, out var assets, "myconfig.config");
|
||||
dotnet.RestoreProjectToDirectory("myproject.csproj", "mypackages", false, out var assets, out var _, pathToNugetConfig: "myconfig.config");
|
||||
|
||||
// Verify
|
||||
var lastArgs = dotnetCliInvoker.GetLastArgs();
|
||||
@@ -126,6 +126,24 @@ namespace Semmle.Extraction.Tests
|
||||
Assert.Contains("/path/to/project2.assets.json", assets);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestDotnetRestoreProjectToDirectory3()
|
||||
{
|
||||
// Setup
|
||||
var dotnetCliInvoker = new DotNetCliInvokerStub(MakeDotnetRestoreOutput());
|
||||
var dotnet = MakeDotnet(dotnetCliInvoker);
|
||||
|
||||
// Execute
|
||||
dotnet.RestoreProjectToDirectory("myproject.csproj", "mypackages", false, out var assets, out var _, pathToNugetConfig: "myconfig.config", force: true);
|
||||
|
||||
// Verify
|
||||
var lastArgs = dotnetCliInvoker.GetLastArgs();
|
||||
Assert.Equal("restore --no-dependencies \"myproject.csproj\" --packages \"mypackages\" /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal --configfile \"myconfig.config\" --force", lastArgs);
|
||||
Assert.Equal(2, assets.Count());
|
||||
Assert.Contains("/path/to/project.assets.json", assets);
|
||||
Assert.Contains("/path/to/project2.assets.json", assets);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestDotnetRestoreSolutionToDirectory1()
|
||||
{
|
||||
|
||||
@@ -165,6 +165,7 @@ namespace Semmle.Extraction.Tests
|
||||
{
|
||||
(var testSubject, var progressMonitor, var files) = TestSetup();
|
||||
|
||||
// NOTE: the ordering DOES matter, later filters takes priority, so the exclude will end up not mattering at all.
|
||||
Environment.SetEnvironmentVariable("LGTM_INDEX_FILTERS", """
|
||||
exclude:c/x/z
|
||||
include:c/x
|
||||
@@ -174,7 +175,8 @@ namespace Semmle.Extraction.Tests
|
||||
|
||||
var expected = GetExpected(
|
||||
[
|
||||
"/a/b/c/x/y/i.cs"
|
||||
"/a/b/c/x/y/i.cs",
|
||||
"/a/b/c/x/z/i.cs"
|
||||
]);
|
||||
|
||||
AssertFileInfoEquivalence(expected, filtered);
|
||||
|
||||
@@ -19,9 +19,10 @@ namespace Semmle.Extraction.Tests
|
||||
|
||||
public bool New(string folder) => true;
|
||||
|
||||
public bool RestoreProjectToDirectory(string project, string directory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> assets, string? pathToNugetConfig = null)
|
||||
public bool RestoreProjectToDirectory(string project, string directory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> assets, out IList<string> outputLines, string? pathToNugetConfig = null, bool force = false)
|
||||
{
|
||||
assets = Array.Empty<string>();
|
||||
outputLines = Array.Empty<string>();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 1.7.7
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.6
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
## 1.7.7
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.7.6
|
||||
lastReleaseVersion: 1.7.7
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-all
|
||||
version: 1.7.6
|
||||
version: 1.7.7
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 1.7.7
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.6
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
## 1.7.7
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.7.6
|
||||
lastReleaseVersion: 1.7.7
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-queries
|
||||
version: 1.7.6
|
||||
version: 1.7.7
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
| newtonsoft.json/13.0.3/lib/net6.0/Newtonsoft.Json.dll |
|
||||
@@ -0,0 +1,11 @@
|
||||
import csharp
|
||||
|
||||
private string getPath(Assembly a) {
|
||||
not a.getCompilation().getOutputAssembly() = a and
|
||||
exists(string s | s = a.getFile().getAbsolutePath() |
|
||||
result = s.substring(s.indexOf("newtonsoft.json"), s.length())
|
||||
)
|
||||
}
|
||||
|
||||
from Assembly a
|
||||
select getPath(a)
|
||||
@@ -0,0 +1,6 @@
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<clear />
|
||||
<add key="x" value="https://abc.abc/packages/" />
|
||||
</packageSources>
|
||||
</configuration>
|
||||
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="DeleteBinObjFolders" BeforeTargets="Clean">
|
||||
<RemoveDir Directories=".\bin" />
|
||||
<RemoveDir Directories=".\obj" />
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.002.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "proj", "proj\proj.csproj", "{6ED00460-7666-4AE9-A405-4B6C8B02279A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {4ED55A1C-066C-43DF-B32E-7EAA035985EE}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,3 @@
|
||||
from create_database_utils import *
|
||||
|
||||
run_codeql_database_create([], lang="csharp", extra_args=["--extractor-option=buildless=true", "--extractor-option=cil=false"])
|
||||
@@ -1,3 +1,20 @@
|
||||
## 0.8.7
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Deleted many deprecated predicates and classes with uppercase `SSL`, `XML`, `URI`, `SSA` etc. in their names. Use the PascalCased versions instead.
|
||||
* Deleted the deprecated `getALocalFlowSucc` predicate and `TaintType` class from the dataflow library.
|
||||
* Deleted the deprecated `Newobj` and `Rethrow` classes, use `NewObj` and `ReThrow` instead.
|
||||
* Deleted the deprecated `getAFirstRead`, `hasAdjacentReads`, `lastRefBeforeRedef`, and `hasLastInputRef` predicates from the SSA library.
|
||||
* Deleted the deprecated `getAReachableRead` predicate from the `AssignableRead` and `VariableRead` classes.
|
||||
* Deleted the deprecated `hasQualifiedName` predicate from the `NamedElement` class.
|
||||
* C# 12: Add extractor support and QL library support for inline arrays.
|
||||
* Fixed a Log forging false positive when logging the value of a nullable simple type. This fix also applies to all other queries that use the simple type sanitizer.
|
||||
* The diagnostic query `cs/diagnostics/successfully-extracted-files`, and therefore the Code Scanning UI measure of scanned C# files, now considers any C# file seen during extraction, even one with some errors, to be extracted / scanned.
|
||||
* Added a new library `semmle.code.csharp.security.dataflow.flowsources.FlowSources`, which provides a new class `ThreatModelFlowSource`. The `ThreatModelFlowSource` class can be used to include sources which match the current *threat model* configuration.
|
||||
* A manual neutral summary model for a callable now blocks all generated summary models for that callable from having any effect.
|
||||
* C# 12: Add extractor support for lambda expressions with parameter defaults like `(int x, int y = 1) => ...` and lambda expressions with a `param` parameter like `(params int[] x) => ...)`.
|
||||
|
||||
## 0.8.6
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
16
csharp/ql/lib/change-notes/released/0.8.7.md
Normal file
16
csharp/ql/lib/change-notes/released/0.8.7.md
Normal file
@@ -0,0 +1,16 @@
|
||||
## 0.8.7
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Deleted many deprecated predicates and classes with uppercase `SSL`, `XML`, `URI`, `SSA` etc. in their names. Use the PascalCased versions instead.
|
||||
* Deleted the deprecated `getALocalFlowSucc` predicate and `TaintType` class from the dataflow library.
|
||||
* Deleted the deprecated `Newobj` and `Rethrow` classes, use `NewObj` and `ReThrow` instead.
|
||||
* Deleted the deprecated `getAFirstRead`, `hasAdjacentReads`, `lastRefBeforeRedef`, and `hasLastInputRef` predicates from the SSA library.
|
||||
* Deleted the deprecated `getAReachableRead` predicate from the `AssignableRead` and `VariableRead` classes.
|
||||
* Deleted the deprecated `hasQualifiedName` predicate from the `NamedElement` class.
|
||||
* C# 12: Add extractor support and QL library support for inline arrays.
|
||||
* Fixed a Log forging false positive when logging the value of a nullable simple type. This fix also applies to all other queries that use the simple type sanitizer.
|
||||
* The diagnostic query `cs/diagnostics/successfully-extracted-files`, and therefore the Code Scanning UI measure of scanned C# files, now considers any C# file seen during extraction, even one with some errors, to be extracted / scanned.
|
||||
* Added a new library `semmle.code.csharp.security.dataflow.flowsources.FlowSources`, which provides a new class `ThreatModelFlowSource`. The `ThreatModelFlowSource` class can be used to include sources which match the current *threat model* configuration.
|
||||
* A manual neutral summary model for a callable now blocks all generated summary models for that callable from having any effect.
|
||||
* C# 12: Add extractor support for lambda expressions with parameter defaults like `(int x, int y = 1) => ...` and lambda expressions with a `param` parameter like `(params int[] x) => ...)`.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user