Merge remote-tracking branch 'origin/codeql-cli-2.16.1' into henrymercer/2.16.0-mergeback

This commit is contained in:
Henry Mercer
2024-01-26 13:53:13 +00:00
998 changed files with 31034 additions and 13698 deletions

View File

@@ -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:

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View 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.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.12.3
lastReleaseVersion: 0.12.4

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 0.12.3
version: 0.12.4
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp

View File

@@ -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.

View File

@@ -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;

View File

@@ -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;

View File

@@ -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()) }

View File

@@ -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)
]
}
}

View 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)
}
}

View File

@@ -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) }

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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)
)
}

View File

@@ -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

View File

@@ -1068,6 +1068,3 @@ module Ssa {
predicate hasUnreachedInstruction = Cached::hasUnreachedInstructionCached/1;
}
/** DEPRECATED: Alias for Ssa */
deprecated module SSA = Ssa;

View File

@@ -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;

View File

@@ -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;

View File

@@ -1068,6 +1068,3 @@ module Ssa {
predicate hasUnreachedInstruction = Cached::hasUnreachedInstructionCached/1;
}
/** DEPRECATED: Alias for Ssa */
deprecated module SSA = Ssa;

View File

@@ -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;

View File

@@ -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

View File

@@ -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,

View File

@@ -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, _)
)
}

View File

@@ -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())
)
}

View File

@@ -1,3 +1,6 @@
description: Remove the old CFG tables
compatibility: full
falsecond.rel: delete
successors.rel: delete
truecond.rel: delete

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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 }

View 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

View 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.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.9.2
lastReleaseVersion: 0.9.3

View File

@@ -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.
*/

View File

@@ -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

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 0.9.2
version: 0.9.3
groups:
- cpp
- queries

View File

@@ -1,2 +0,0 @@
__builtin_foobar(i)i
__builtin_malloc(i,i,i,f*)f

View File

@@ -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 |

View File

@@ -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()

View File

@@ -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

View File

@@ -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 | |

View File

@@ -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 |

View File

@@ -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

View File

@@ -31,3 +31,4 @@ uniqueContentApprox
identityLocalStep
missingArgumentCall
multipleArgumentCall
lambdaCallEnclosingCallableMismatch

View File

@@ -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 |

View File

@@ -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
}
}

View File

@@ -193,3 +193,4 @@ uniqueContentApprox
identityLocalStep
missingArgumentCall
multipleArgumentCall
lambdaCallEnclosingCallableMismatch

View File

@@ -27,3 +27,4 @@ uniqueContentApprox
identityLocalStep
missingArgumentCall
multipleArgumentCall
lambdaCallEnclosingCallableMismatch

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -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

View File

@@ -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 |

View File

@@ -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()
}

View 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);
}

View 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;
};
}

View 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 |

View 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

View 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;

View File

@@ -99,3 +99,4 @@ uniqueContentApprox
identityLocalStep
missingArgumentCall
multipleArgumentCall
lambdaCallEnclosingCallableMismatch

View File

@@ -42,3 +42,4 @@ uniqueContentApprox
identityLocalStep
missingArgumentCall
multipleArgumentCall
lambdaCallEnclosingCallableMismatch

View File

@@ -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 | * ... |

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,3 @@
description: Remove support for inline arrays.
compatibility: backwards
types.rel: run types.qlo

View File

@@ -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);
}
}
});

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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;

View File

@@ -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,
}
}

View File

@@ -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>

View File

@@ -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()
{

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -1,3 +1,7 @@
## 1.7.7
No user-facing changes.
## 1.7.6
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 1.7.7
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.7.6
lastReleaseVersion: 1.7.7

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-all
version: 1.7.6
version: 1.7.7
groups:
- csharp
- solorigate

View File

@@ -1,3 +1,7 @@
## 1.7.7
No user-facing changes.
## 1.7.6
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 1.7.7
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.7.6
lastReleaseVersion: 1.7.7

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-queries
version: 1.7.6
version: 1.7.7
groups:
- csharp
- solorigate

View File

@@ -0,0 +1 @@
| newtonsoft.json/13.0.3/lib/net6.0/Newtonsoft.Json.dll |

View File

@@ -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)

View File

@@ -0,0 +1,6 @@
class Program
{
static void Main(string[] args)
{
}
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="x" value="https://abc.abc/packages/" />
</packageSources>
</configuration>

View File

@@ -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>

View File

@@ -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

View File

@@ -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"])

View File

@@ -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

View 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