Merge branch 'main' into dbsinks2

This commit is contained in:
Geoffrey White
2023-03-14 16:26:36 +00:00
1457 changed files with 33594 additions and 12492 deletions

21
.git-blame-ignore-revs Normal file
View File

@@ -0,0 +1,21 @@
# .git-blame-ignore-revs
# Auto-formatted Java
730eae952139209fe9fdf598541d608f4c0c0c84
# Auto-formatted C#
5ad7ed49dd3de03ec6dcfcb6848758a6a987e11c
# Auto-formatted C/C++
ef97e539ec1971494d4bba5cafe82e00bc8217ac
# Auto-formatted Python
21d5fa836b3a7d020ba45e8b8168b145a9772131
# Auto-formatted JavaScript
8d97fe9ed327a9546ff2eaf515cf0f5214deddd9
# Auto-formatted Ruby
a5d229903d2f12d45f2c2c38822f1d0e7504ae7f
# Auto-formatted Go
08c658e66bf867090033ea096e244a93d46c0aa7
# Auto-formatted Swift
711d7057f79fb7d72fc3b35e010bd018f9009169
# Auto-formatted shared ql packs
3640b6d3a8ce9edf8e1d3ed106fe8526cf255bc0
# Auto-formatted taint tracking files
159d8e978c51959b380838c080d891b66e763b19

View File

@@ -2,9 +2,9 @@
/csharp/ @github/codeql-csharp
/go/ @github/codeql-go
/java/ @github/codeql-java
/javascript/ @github/codeql-dynamic
/python/ @github/codeql-dynamic
/ruby/ @github/codeql-dynamic
/javascript/ @github/codeql-javascript
/python/ @github/codeql-python
/ruby/ @github/codeql-ruby
/swift/ @github/codeql-swift
/misc/codegen/ @github/codeql-swift
/java/kotlin-extractor/ @github/codeql-kotlin

View File

@@ -1,3 +1,7 @@
## 0.5.4
No user-facing changes.
## 0.5.3
No user-facing changes.

View File

@@ -0,0 +1,12 @@
---
category: minorAnalysis
---
* Deleted the deprecated `hasGeneratedCopyConstructor` and `hasGeneratedCopyAssignmentOperator` predicates from the `Folder` class.
* Deleted the deprecated `getPath` and `getFolder` predicates from the `XmlFile` class.
* Deleted the deprecated `getMustlockFunction`, `getTrylockFunction`, `getLockFunction`, and `getUnlockFunction` predicates from the `MutexType` class.
* Deleted the deprecated `getPosInBasicBlock` predicate from the `SubBasicBlock` class.
* Deleted the deprecated `getExpr` predicate from the `PointerDereferenceExpr` class.
* Deleted the deprecated `getUseInstruction` and `getDefinitionInstruction` predicates from the `Operand` class.
* Deleted the deprecated `isInParameter`, `isInParameterPointer`, and `isInQualifier` predicates from the `FunctionInput` class.
* Deleted the deprecated `isOutParameterPointer`, `isOutQualifier`, `isOutReturnValue`, and `isOutReturnPointer` predicate from the `FunctionOutput` class.
* Deleted the deprecated 3-argument `isGuardPhi` predicate from the `RangeSsaDefinition` class.

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Added support for merging two `PathGraph`s via disjoint union to allow results from multiple data flow computations in a single `path-problem` query.

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.5.3
lastReleaseVersion: 0.5.4

View File

@@ -243,3 +243,111 @@ module MakeWithState<StateConfigSig Config> implements DataFlowSig {
import Impl<C>
}
signature class PathNodeSig {
/** Gets a textual representation of this element. */
string toString();
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
);
/** Gets the underlying `Node`. */
Node getNode();
}
signature module PathGraphSig<PathNodeSig PathNode> {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
predicate edges(PathNode a, PathNode b);
/** Holds if `n` is a node in the graph of data flow path explanations. */
predicate nodes(PathNode n, string key, string val);
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out);
}
/**
* Constructs a `PathGraph` from two `PathGraph`s by disjoint union.
*/
module MergePathGraph<
PathNodeSig PathNode1, PathNodeSig PathNode2, PathGraphSig<PathNode1> Graph1,
PathGraphSig<PathNode2> Graph2>
{
private newtype TPathNode =
TPathNode1(PathNode1 p) or
TPathNode2(PathNode2 p)
/** A node in a graph of path explanations that is formed by disjoint union of the two given graphs. */
class PathNode extends TPathNode {
/** Gets this as a projection on the first given `PathGraph`. */
PathNode1 asPathNode1() { this = TPathNode1(result) }
/** Gets this as a projection on the second given `PathGraph`. */
PathNode2 asPathNode2() { this = TPathNode2(result) }
/** Gets a textual representation of this element. */
string toString() {
result = this.asPathNode1().toString() or
result = this.asPathNode2().toString()
}
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.asPathNode1().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) or
this.asPathNode2().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
Node getNode() {
result = this.asPathNode1().getNode() or
result = this.asPathNode2().getNode()
}
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
*/
module PathGraph implements PathGraphSig<PathNode> {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) {
Graph1::edges(a.asPathNode1(), b.asPathNode1()) or
Graph2::edges(a.asPathNode2(), b.asPathNode2())
}
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
Graph1::nodes(n.asPathNode1(), key, val) or
Graph2::nodes(n.asPathNode2(), key, val)
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Graph1::subpaths(arg.asPathNode1(), par.asPathNode1(), ret.asPathNode1(), out.asPathNode1()) or
Graph2::subpaths(arg.asPathNode2(), par.asPathNode2(), ret.asPathNode2(), out.asPathNode2())
}
}
}

View File

@@ -456,6 +456,7 @@ module Impl<FullStateConfigSig Config> {
* The Boolean `cc` records whether the node is reached through an
* argument in a call.
*/
pragma[assume_small_delta]
private predicate fwdFlow(NodeEx node, Cc cc) {
sourceNode(node, _) and
if hasSourceCallCtx() then cc = true else cc = false
@@ -3156,7 +3157,7 @@ module Impl<FullStateConfigSig Config> {
/**
* Provides the query predicates needed to include a graph in a path-problem query.
*/
module PathGraph {
module PathGraph implements PathGraphSig<PathNode> {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b }

View File

@@ -7,7 +7,8 @@ import TaintTrackingParameter::Public
private import TaintTrackingParameter::Private
private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> implements
DataFlowInternal::FullStateConfigSig {
DataFlowInternal::FullStateConfigSig
{
import Config
predicate isBarrier(DataFlow::Node node) {

View File

@@ -936,6 +936,15 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<
bounded(cast.getOperand(), b, delta, upper, fromBackEdge, origdelta, reason)
}
/**
* Computes a normal form of `x` where -0.0 has changed to +0.0. This can be
* needed on the lesser side of a floating-point comparison or on both sides of
* a floating point equality because QL does not follow IEEE in floating-point
* comparisons but instead defines -0.0 to be less than and distinct from 0.0.
*/
bindingset[x]
private float normalizeFloatUp(float x) { result = x + 0.0 }
/**
* Holds if `b + delta` is a valid bound for `e`.
* - `upper = true` : `e <= b + delta`
@@ -1020,6 +1029,15 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<
or
upper = false and delta = D::fromFloat(D::toFloat(d1).minimum(D::toFloat(d2)))
)
or
exists(SemExpr mid, D::Delta d, float f |
e.(SemNegateExpr).getOperand() = mid and
b instanceof SemZeroBound and
bounded(mid, b, d, upper.booleanNot(), fromBackEdge, origdelta, reason) and
f = normalizeFloatUp(-D::toFloat(d)) and
delta = D::fromFloat(f) and
if semPositive(e) then f >= 0 else any()
)
)
}

View File

@@ -0,0 +1,132 @@
/**
* Wrapper for the semantic range analysis library that mimics the
* interface of the simple range analysis library.
*/
private import cpp
private import semmle.code.cpp.ir.IR
private import experimental.semmle.code.cpp.semantic.SemanticBound
private import experimental.semmle.code.cpp.semantic.SemanticExprSpecific
private import RangeAnalysis
/**
* Gets the lower bound of the expression.
*
* Note: expressions in C/C++ are often implicitly or explicitly cast to a
* different result type. Such casts can cause the value of the expression
* to overflow or to be truncated. This predicate computes the lower bound
* of the expression without including the effect of the casts. To compute
* the lower bound of the expression after all the casts have been applied,
* call `lowerBound` like this:
*
* `lowerBound(expr.getFullyConverted())`
*/
float lowerBound(Expr expr) {
exists(Instruction i, SemBound b | i.getAst() = expr and b instanceof SemZeroBound |
semBounded(getSemanticExpr(i), b, result, false, _)
)
}
/**
* Gets the upper bound of the expression.
*
* Note: expressions in C/C++ are often implicitly or explicitly cast to a
* different result type. Such casts can cause the value of the expression
* to overflow or to be truncated. This predicate computes the upper bound
* of the expression without including the effect of the casts. To compute
* the upper bound of the expression after all the casts have been applied,
* call `upperBound` like this:
*
* `upperBound(expr.getFullyConverted())`
*/
float upperBound(Expr expr) {
exists(Instruction i, SemBound b | i.getAst() = expr and b instanceof SemZeroBound |
semBounded(getSemanticExpr(i), b, result, true, _)
)
}
/**
* Holds if the upper bound of `expr` may have been widened. This means the
* upper bound is in practice likely to be overly wide.
*/
predicate upperBoundMayBeWidened(Expr e) { none() }
/**
* Holds if `expr` has a provably empty range. For example:
*
* 10 < expr and expr < 5
*
* The range of an expression can only be empty if it can never be
* executed. For example:
*
* ```cpp
* if (10 < x) {
* if (x < 5) {
* // Unreachable code
* return x; // x has an empty range: 10 < x && x < 5
* }
* }
* ```
*/
predicate exprWithEmptyRange(Expr expr) { lowerBound(expr) > upperBound(expr) }
/** Holds if the definition might overflow negatively. */
predicate defMightOverflowNegatively(RangeSsaDefinition def, StackVariable v) { none() }
/** Holds if the definition might overflow positively. */
predicate defMightOverflowPositively(RangeSsaDefinition def, StackVariable v) { none() }
/**
* Holds if the definition might overflow (either positively or
* negatively).
*/
predicate defMightOverflow(RangeSsaDefinition def, StackVariable v) {
defMightOverflowNegatively(def, v) or
defMightOverflowPositively(def, v)
}
/**
* Holds if the expression might overflow negatively. This predicate
* does not consider the possibility that the expression might overflow
* due to a conversion.
*/
predicate exprMightOverflowNegatively(Expr expr) { none() }
/**
* Holds if the expression might overflow negatively. Conversions
* are also taken into account. For example the expression
* `(int16)(x+y)` might overflow due to the `(int16)` cast, rather than
* due to the addition.
*/
predicate convertedExprMightOverflowNegatively(Expr expr) {
exprMightOverflowNegatively(expr) or
convertedExprMightOverflowNegatively(expr.getConversion())
}
/**
* Holds if the expression might overflow positively. This predicate
* does not consider the possibility that the expression might overflow
* due to a conversion.
*/
predicate exprMightOverflowPositively(Expr expr) { none() }
/**
* Holds if the expression might overflow positively. Conversions
* are also taken into account. For example the expression
* `(int16)(x+y)` might overflow due to the `(int16)` cast, rather than
* due to the addition.
*/
predicate convertedExprMightOverflowPositively(Expr expr) {
exprMightOverflowPositively(expr) or
convertedExprMightOverflowPositively(expr.getConversion())
}
/**
* Holds if the expression might overflow (either positively or
* negatively). The possibility that the expression might overflow
* due to an implicit or explicit cast is also considered.
*/
predicate convertedExprMightOverflow(Expr expr) {
convertedExprMightOverflowNegatively(expr) or
convertedExprMightOverflowPositively(expr)
}

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 0.5.4-dev
version: 0.5.5-dev
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp

View File

@@ -227,18 +227,6 @@ class Class extends UserType {
result = this.accessOfBaseMember(member.getDeclaringType(), member.getASpecifier())
}
/**
* DEPRECATED: name changed to `hasImplicitCopyConstructor` to reflect that
* `= default` members are no longer included.
*/
deprecated predicate hasGeneratedCopyConstructor() { this.hasImplicitCopyConstructor() }
/**
* DEPRECATED: name changed to `hasImplicitCopyAssignmentOperator` to
* reflect that `= default` members are no longer included.
*/
deprecated predicate hasGeneratedCopyAssignmentOperator() { this.hasImplicitCopyConstructor() }
/**
* Holds if this class, struct or union has an implicitly-declared copy
* constructor that is not _deleted_. This predicate is more accurate than

View File

@@ -619,11 +619,10 @@ private class DirectAccessHolder extends Element {
/**
* Like `couldAccessMember` but only contains derivations in which either
* (5.2), (5.3) or (5.4) must be invoked. In other words, the `this`
* parameter is not ignored. This restriction makes it feasible to fully
* enumerate this predicate even on large code bases. We check for 11.4 as
* part of (5.3), since this further limits the number of tuples produced by
* this predicate.
* parameter is not ignored. We check for 11.4 as part of (5.3), since
* this further limits the number of tuples produced by this predicate.
*/
pragma[inline]
predicate thisCouldAccessMember(Class memberClass, AccessSpecifier memberAccess, Class derived) {
// Only (5.4) is recursive, and chains of invocations of (5.4) can always
// be collapsed to one invocation by the transitivity of 11.2/4.
@@ -665,7 +664,9 @@ private class DirectAccessHolder extends Element {
// bypasses `p`. Then that path must be public, or we are in case 2.
exists(AccessSpecifier public | public.hasName("public") |
exists(Class between, Class p |
between.accessOfBaseMember(memberClass, memberAccess).hasName("protected") and
between
.accessOfBaseMember(pragma[only_bind_into](memberClass), memberAccess)
.hasName("protected") and
this.isFriendOfOrEqualTo(p) and
(
// This is case 1 from above. If `p` derives privately from `between`

View File

@@ -159,7 +159,8 @@ class NameQualifyingElement extends Element, @namequalifyingelement {
* A special name-qualifying element. For example: `__super`.
*/
library class SpecialNameQualifyingElement extends NameQualifyingElement,
@specialnamequalifyingelement {
@specialnamequalifyingelement
{
/** Gets the name of this special qualifying element. */
override string getName() { specialnamequalifyingelements(underlyingElement(this), result) }

View File

@@ -108,20 +108,6 @@ class XmlFile extends XmlParent, File {
/** Gets the name of this XML file. */
override string getName() { result = File.super.getAbsolutePath() }
/**
* DEPRECATED: Use `getAbsolutePath()` instead.
*
* Gets the path of this XML file.
*/
deprecated string getPath() { result = this.getAbsolutePath() }
/**
* DEPRECATED: Use `getParentContainer().getAbsolutePath()` instead.
*
* Gets the path of the folder that contains this XML file.
*/
deprecated string getFolder() { result = this.getParentContainer().getAbsolutePath() }
/** Gets the encoding of this XML file. */
string getEncoding() { xmlEncoding(this, result) }

View File

@@ -59,26 +59,6 @@ abstract class MutexType extends Type {
* Gets a call that unlocks any mutex of this type.
*/
FunctionCall getUnlockAccess() { this.unlockAccess(result, _) }
/**
* DEPRECATED: use mustlockAccess(fc, arg) instead.
*/
deprecated Function getMustlockFunction() { result = this.getMustlockAccess().getTarget() }
/**
* DEPRECATED: use trylockAccess(fc, arg) instead.
*/
deprecated Function getTrylockFunction() { result = this.getTrylockAccess().getTarget() }
/**
* DEPRECATED: use lockAccess(fc, arg) instead.
*/
deprecated Function getLockFunction() { result = this.getLockAccess().getTarget() }
/**
* DEPRECATED: use unlockAccess(fc, arg) instead.
*/
deprecated Function getUnlockFunction() { result = this.getUnlockAccess().getTarget() }
}
/**

View File

@@ -75,13 +75,6 @@ class SubBasicBlock extends ControlFlowNodeBase {
)
}
/**
* DEPRECATED: use `getRankInBasicBlock` instead. Note that this predicate
* returns a 0-based position, while `getRankInBasicBlock` returns a 1-based
* position.
*/
deprecated int getPosInBasicBlock(BasicBlock bb) { result = this.getRankInBasicBlock(bb) - 1 }
pragma[noinline]
private int getIndexInBasicBlock(BasicBlock bb) { this = bb.getNode(result) }

View File

@@ -243,3 +243,111 @@ module MakeWithState<StateConfigSig Config> implements DataFlowSig {
import Impl<C>
}
signature class PathNodeSig {
/** Gets a textual representation of this element. */
string toString();
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
);
/** Gets the underlying `Node`. */
Node getNode();
}
signature module PathGraphSig<PathNodeSig PathNode> {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
predicate edges(PathNode a, PathNode b);
/** Holds if `n` is a node in the graph of data flow path explanations. */
predicate nodes(PathNode n, string key, string val);
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out);
}
/**
* Constructs a `PathGraph` from two `PathGraph`s by disjoint union.
*/
module MergePathGraph<
PathNodeSig PathNode1, PathNodeSig PathNode2, PathGraphSig<PathNode1> Graph1,
PathGraphSig<PathNode2> Graph2>
{
private newtype TPathNode =
TPathNode1(PathNode1 p) or
TPathNode2(PathNode2 p)
/** A node in a graph of path explanations that is formed by disjoint union of the two given graphs. */
class PathNode extends TPathNode {
/** Gets this as a projection on the first given `PathGraph`. */
PathNode1 asPathNode1() { this = TPathNode1(result) }
/** Gets this as a projection on the second given `PathGraph`. */
PathNode2 asPathNode2() { this = TPathNode2(result) }
/** Gets a textual representation of this element. */
string toString() {
result = this.asPathNode1().toString() or
result = this.asPathNode2().toString()
}
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.asPathNode1().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) or
this.asPathNode2().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
Node getNode() {
result = this.asPathNode1().getNode() or
result = this.asPathNode2().getNode()
}
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
*/
module PathGraph implements PathGraphSig<PathNode> {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) {
Graph1::edges(a.asPathNode1(), b.asPathNode1()) or
Graph2::edges(a.asPathNode2(), b.asPathNode2())
}
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
Graph1::nodes(n.asPathNode1(), key, val) or
Graph2::nodes(n.asPathNode2(), key, val)
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Graph1::subpaths(arg.asPathNode1(), par.asPathNode1(), ret.asPathNode1(), out.asPathNode1()) or
Graph2::subpaths(arg.asPathNode2(), par.asPathNode2(), ret.asPathNode2(), out.asPathNode2())
}
}
}

View File

@@ -456,6 +456,7 @@ module Impl<FullStateConfigSig Config> {
* The Boolean `cc` records whether the node is reached through an
* argument in a call.
*/
pragma[assume_small_delta]
private predicate fwdFlow(NodeEx node, Cc cc) {
sourceNode(node, _) and
if hasSourceCallCtx() then cc = true else cc = false
@@ -3156,7 +3157,7 @@ module Impl<FullStateConfigSig Config> {
/**
* Provides the query predicates needed to include a graph in a path-problem query.
*/
module PathGraph {
module PathGraph implements PathGraphSig<PathNode> {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b }

View File

@@ -75,13 +75,6 @@ class SubBasicBlock extends ControlFlowNodeBase {
)
}
/**
* DEPRECATED: use `getRankInBasicBlock` instead. Note that this predicate
* returns a 0-based position, while `getRankInBasicBlock` returns a 1-based
* position.
*/
deprecated int getPosInBasicBlock(BasicBlock bb) { result = this.getRankInBasicBlock(bb) - 1 }
pragma[noinline]
private int getIndexInBasicBlock(BasicBlock bb) { this = bb.getNode(result) }

View File

@@ -7,7 +7,8 @@ import TaintTrackingParameter::Public
private import TaintTrackingParameter::Private
private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> implements
DataFlowInternal::FullStateConfigSig {
DataFlowInternal::FullStateConfigSig
{
import Config
predicate isBarrier(DataFlow::Node node) {

View File

@@ -569,7 +569,8 @@ class BuiltInOperationBuiltInAddressOf extends UnaryOperation, BuiltInOperation,
* ```
*/
class BuiltInOperationIsTriviallyConstructible extends BuiltInOperation,
@istriviallyconstructibleexpr {
@istriviallyconstructibleexpr
{
override string toString() { result = "__is_trivially_constructible" }
override string getAPrimaryQlClass() { result = "BuiltInOperationIsTriviallyConstructible" }
@@ -619,7 +620,8 @@ class BuiltInOperationIsNothrowDestructible extends BuiltInOperation, @isnothrow
* bool v = __is_trivially_destructible(MyType);
* ```
*/
class BuiltInOperationIsTriviallyDestructible extends BuiltInOperation, @istriviallydestructibleexpr {
class BuiltInOperationIsTriviallyDestructible extends BuiltInOperation, @istriviallydestructibleexpr
{
override string toString() { result = "__is_trivially_destructible" }
override string getAPrimaryQlClass() { result = "BuiltInOperationIsTriviallyDestructible" }
@@ -738,7 +740,8 @@ class BuiltInOperationIsLiteralType extends BuiltInOperation, @isliteraltypeexpr
* ```
*/
class BuiltInOperationHasTrivialMoveConstructor extends BuiltInOperation,
@hastrivialmoveconstructorexpr {
@hastrivialmoveconstructorexpr
{
override string toString() { result = "__has_trivial_move_constructor" }
override string getAPrimaryQlClass() { result = "BuiltInOperationHasTrivialMoveConstructor" }
@@ -1034,7 +1037,8 @@ class BuiltInOperationIsAggregate extends BuiltInOperation, @isaggregate {
* ```
*/
class BuiltInOperationHasUniqueObjectRepresentations extends BuiltInOperation,
@hasuniqueobjectrepresentations {
@hasuniqueobjectrepresentations
{
override string toString() { result = "__has_unique_object_representations" }
override string getAPrimaryQlClass() { result = "BuiltInOperationHasUniqueObjectRepresentations" }
@@ -1107,7 +1111,8 @@ class BuiltInOperationIsLayoutCompatible extends BuiltInOperation, @islayoutcomp
* ```
*/
class BuiltInOperationIsPointerInterconvertibleBaseOf extends BuiltInOperation,
@ispointerinterconvertiblebaseof {
@ispointerinterconvertiblebaseof
{
override string toString() { result = "__is_pointer_interconvertible_base_of" }
override string getAPrimaryQlClass() {

View File

@@ -719,13 +719,6 @@ class ReferenceToExpr extends Conversion, @reference_to {
class PointerDereferenceExpr extends UnaryOperation, @indirect {
override string getAPrimaryQlClass() { result = "PointerDereferenceExpr" }
/**
* DEPRECATED: Use getOperand() instead.
*
* Gets the expression that is being dereferenced.
*/
deprecated Expr getExpr() { result = this.getOperand() }
override string getOperator() { result = "*" }
override int getPrecedence() { result = 16 }

View File

@@ -243,3 +243,111 @@ module MakeWithState<StateConfigSig Config> implements DataFlowSig {
import Impl<C>
}
signature class PathNodeSig {
/** Gets a textual representation of this element. */
string toString();
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
);
/** Gets the underlying `Node`. */
Node getNode();
}
signature module PathGraphSig<PathNodeSig PathNode> {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
predicate edges(PathNode a, PathNode b);
/** Holds if `n` is a node in the graph of data flow path explanations. */
predicate nodes(PathNode n, string key, string val);
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out);
}
/**
* Constructs a `PathGraph` from two `PathGraph`s by disjoint union.
*/
module MergePathGraph<
PathNodeSig PathNode1, PathNodeSig PathNode2, PathGraphSig<PathNode1> Graph1,
PathGraphSig<PathNode2> Graph2>
{
private newtype TPathNode =
TPathNode1(PathNode1 p) or
TPathNode2(PathNode2 p)
/** A node in a graph of path explanations that is formed by disjoint union of the two given graphs. */
class PathNode extends TPathNode {
/** Gets this as a projection on the first given `PathGraph`. */
PathNode1 asPathNode1() { this = TPathNode1(result) }
/** Gets this as a projection on the second given `PathGraph`. */
PathNode2 asPathNode2() { this = TPathNode2(result) }
/** Gets a textual representation of this element. */
string toString() {
result = this.asPathNode1().toString() or
result = this.asPathNode2().toString()
}
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.asPathNode1().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) or
this.asPathNode2().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
Node getNode() {
result = this.asPathNode1().getNode() or
result = this.asPathNode2().getNode()
}
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
*/
module PathGraph implements PathGraphSig<PathNode> {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) {
Graph1::edges(a.asPathNode1(), b.asPathNode1()) or
Graph2::edges(a.asPathNode2(), b.asPathNode2())
}
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
Graph1::nodes(n.asPathNode1(), key, val) or
Graph2::nodes(n.asPathNode2(), key, val)
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Graph1::subpaths(arg.asPathNode1(), par.asPathNode1(), ret.asPathNode1(), out.asPathNode1()) or
Graph2::subpaths(arg.asPathNode2(), par.asPathNode2(), ret.asPathNode2(), out.asPathNode2())
}
}
}

View File

@@ -456,6 +456,7 @@ module Impl<FullStateConfigSig Config> {
* The Boolean `cc` records whether the node is reached through an
* argument in a call.
*/
pragma[assume_small_delta]
private predicate fwdFlow(NodeEx node, Cc cc) {
sourceNode(node, _) and
if hasSourceCallCtx() then cc = true else cc = false
@@ -3156,7 +3157,7 @@ module Impl<FullStateConfigSig Config> {
/**
* Provides the query predicates needed to include a graph in a path-problem query.
*/
module PathGraph {
module PathGraph implements PathGraphSig<PathNode> {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b }

View File

@@ -7,7 +7,8 @@ import TaintTrackingParameter::Public
private import TaintTrackingParameter::Private
private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> implements
DataFlowInternal::FullStateConfigSig {
DataFlowInternal::FullStateConfigSig
{
import Config
predicate isBarrier(DataFlow::Node node) {

View File

@@ -1082,7 +1082,8 @@ module Opcode {
* See the `CallSideEffectInstruction` documentation for more details.
*/
class CallSideEffect extends WriteSideEffectOpcode, EscapedWriteOpcode, MayWriteOpcode,
ReadSideEffectOpcode, EscapedReadOpcode, MayReadOpcode, TCallSideEffect {
ReadSideEffectOpcode, EscapedReadOpcode, MayReadOpcode, TCallSideEffect
{
final override string toString() { result = "CallSideEffect" }
}
@@ -1092,7 +1093,8 @@ module Opcode {
* See the `CallReadSideEffectInstruction` documentation for more details.
*/
class CallReadSideEffect extends ReadSideEffectOpcode, EscapedReadOpcode, MayReadOpcode,
TCallReadSideEffect {
TCallReadSideEffect
{
final override string toString() { result = "CallReadSideEffect" }
}
@@ -1102,7 +1104,8 @@ module Opcode {
* See the `IndirectReadSideEffectInstruction` documentation for more details.
*/
class IndirectReadSideEffect extends ReadSideEffectOpcode, IndirectReadOpcode,
TIndirectReadSideEffect {
TIndirectReadSideEffect
{
final override string toString() { result = "IndirectReadSideEffect" }
}
@@ -1112,7 +1115,8 @@ module Opcode {
* See the `IndirectMustWriteSideEffectInstruction` documentation for more details.
*/
class IndirectMustWriteSideEffect extends WriteSideEffectOpcode, IndirectWriteOpcode,
TIndirectMustWriteSideEffect {
TIndirectMustWriteSideEffect
{
final override string toString() { result = "IndirectMustWriteSideEffect" }
}
@@ -1122,7 +1126,8 @@ module Opcode {
* See the `IndirectMayWriteSideEffectInstruction` documentation for more details.
*/
class IndirectMayWriteSideEffect extends WriteSideEffectOpcode, IndirectWriteOpcode,
MayWriteOpcode, TIndirectMayWriteSideEffect {
MayWriteOpcode, TIndirectMayWriteSideEffect
{
final override string toString() { result = "IndirectMayWriteSideEffect" }
}
@@ -1132,7 +1137,8 @@ module Opcode {
* See the `BufferReadSideEffectInstruction` documentation for more details.
*/
class BufferReadSideEffect extends ReadSideEffectOpcode, UnsizedBufferReadOpcode,
TBufferReadSideEffect {
TBufferReadSideEffect
{
final override string toString() { result = "BufferReadSideEffect" }
}
@@ -1142,7 +1148,8 @@ module Opcode {
* See the `BufferMustWriteSideEffectInstruction` documentation for more details.
*/
class BufferMustWriteSideEffect extends WriteSideEffectOpcode, UnsizedBufferWriteOpcode,
TBufferMustWriteSideEffect {
TBufferMustWriteSideEffect
{
final override string toString() { result = "BufferMustWriteSideEffect" }
}
@@ -1152,7 +1159,8 @@ module Opcode {
* See the `BufferMayWriteSideEffectInstruction` documentation for more details.
*/
class BufferMayWriteSideEffect extends WriteSideEffectOpcode, UnsizedBufferWriteOpcode,
MayWriteOpcode, TBufferMayWriteSideEffect {
MayWriteOpcode, TBufferMayWriteSideEffect
{
final override string toString() { result = "BufferMayWriteSideEffect" }
}
@@ -1162,7 +1170,8 @@ module Opcode {
* See the `SizedBufferReadSideEffectInstruction` documentation for more details.
*/
class SizedBufferReadSideEffect extends ReadSideEffectOpcode, SizedBufferReadOpcode,
TSizedBufferReadSideEffect {
TSizedBufferReadSideEffect
{
final override string toString() { result = "SizedBufferReadSideEffect" }
}
@@ -1172,7 +1181,8 @@ module Opcode {
* See the `SizedBufferMustWriteSideEffectInstruction` documentation for more details.
*/
class SizedBufferMustWriteSideEffect extends WriteSideEffectOpcode, SizedBufferWriteOpcode,
TSizedBufferMustWriteSideEffect {
TSizedBufferMustWriteSideEffect
{
final override string toString() { result = "SizedBufferMustWriteSideEffect" }
}
@@ -1182,7 +1192,8 @@ module Opcode {
* See the `SizedBufferMayWriteSideEffectInstruction` documentation for more details.
*/
class SizedBufferMayWriteSideEffect extends WriteSideEffectOpcode, SizedBufferWriteOpcode,
MayWriteOpcode, TSizedBufferMayWriteSideEffect {
MayWriteOpcode, TSizedBufferMayWriteSideEffect
{
final override string toString() { result = "SizedBufferMayWriteSideEffect" }
}
@@ -1192,7 +1203,8 @@ module Opcode {
* See the `InitializeDynamicAllocationInstruction` documentation for more details.
*/
class InitializeDynamicAllocation extends SideEffectOpcode, EntireAllocationWriteOpcode,
TInitializeDynamicAllocation {
TInitializeDynamicAllocation
{
final override string toString() { result = "InitializeDynamicAllocation" }
}
@@ -1221,7 +1233,8 @@ module Opcode {
* See the `InlineAsmInstruction` documentation for more details.
*/
class InlineAsm extends Opcode, EscapedWriteOpcode, MayWriteOpcode, EscapedReadOpcode,
MayReadOpcode, TInlineAsm {
MayReadOpcode, TInlineAsm
{
final override string toString() { result = "InlineAsm" }
final override predicate hasOperandInternal(OperandTag tag) {

View File

@@ -87,22 +87,6 @@ class Operand extends TStageOperand {
this.getDefinitionOverlap() instanceof MustExactlyOverlap
}
/**
* DEPRECATED: renamed to `getUse`.
*
* Gets the `Instruction` that consumes this operand.
*/
deprecated final Instruction getUseInstruction() { result = this.getUse() }
/**
* DEPRECATED: use `getAnyDef` or `getDef`. The exact replacement for this
* predicate is `getAnyDef`, but most uses of this predicate should probably
* be replaced with `getDef`.
*
* Gets the `Instruction` whose result is the value of the operand.
*/
deprecated final Instruction getDefinitionInstruction() { result = this.getAnyDef() }
/**
* Gets the overlap relationship between the operand's definition and its use.
*/

View File

@@ -246,7 +246,8 @@ class VariableMemoryLocation extends TVariableMemoryLocation, AllocationMemoryLo
}
class EntireAllocationMemoryLocation extends TEntireAllocationMemoryLocation,
AllocationMemoryLocation {
AllocationMemoryLocation
{
EntireAllocationMemoryLocation() { this = TEntireAllocationMemoryLocation(var, isMayAccess) }
final override string toStringInternal() { result = var.toString() }

View File

@@ -87,22 +87,6 @@ class Operand extends TStageOperand {
this.getDefinitionOverlap() instanceof MustExactlyOverlap
}
/**
* DEPRECATED: renamed to `getUse`.
*
* Gets the `Instruction` that consumes this operand.
*/
deprecated final Instruction getUseInstruction() { result = this.getUse() }
/**
* DEPRECATED: use `getAnyDef` or `getDef`. The exact replacement for this
* predicate is `getAnyDef`, but most uses of this predicate should probably
* be replaced with `getDef`.
*
* Gets the `Instruction` whose result is the value of the operand.
*/
deprecated final Instruction getDefinitionInstruction() { result = this.getAnyDef() }
/**
* Gets the overlap relationship between the operand's definition and its use.
*/

View File

@@ -511,7 +511,8 @@ abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
* calls other than constructor calls.
*/
class TranslatedArgumentExprSideEffect extends TranslatedArgumentSideEffect,
TTranslatedArgumentExprSideEffect {
TTranslatedArgumentExprSideEffect
{
Expr arg;
TranslatedArgumentExprSideEffect() {
@@ -546,7 +547,8 @@ class TranslatedArgumentExprSideEffect extends TranslatedArgumentSideEffect,
* calls to non-static member functions.
*/
class TranslatedStructorQualifierSideEffect extends TranslatedArgumentSideEffect,
TTranslatedStructorQualifierSideEffect {
TTranslatedStructorQualifierSideEffect
{
TranslatedStructorQualifierSideEffect() {
this = TTranslatedStructorQualifierSideEffect(call, sideEffectOpcode) and
index = -1

View File

@@ -34,7 +34,8 @@ abstract class TranslatedCondition extends TranslatedElement {
}
abstract class TranslatedFlexibleCondition extends TranslatedCondition, ConditionContext,
TTranslatedFlexibleCondition {
TTranslatedFlexibleCondition
{
TranslatedFlexibleCondition() { this = TTranslatedFlexibleCondition(expr) }
final override TranslatedElement getChild(int id) { id = 0 and result = getOperand() }

View File

@@ -75,7 +75,8 @@ abstract class TranslatedLocalVariableDeclaration extends TranslatedVariableInit
* The IR translation of a local variable declaration within a declaration statement.
*/
class TranslatedAutoVariableDeclarationEntry extends TranslatedLocalVariableDeclaration,
TranslatedDeclarationEntry {
TranslatedDeclarationEntry
{
StackVariable var;
TranslatedAutoVariableDeclarationEntry() { var = entry.getDeclaration() }
@@ -217,7 +218,8 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
* with a dynamic initializer.
*/
class TranslatedStaticLocalVariableInitialization extends TranslatedElement,
TranslatedLocalVariableDeclaration, TTranslatedStaticLocalVariableInitialization {
TranslatedLocalVariableDeclaration, TTranslatedStaticLocalVariableInitialization
{
IRVariableDeclarationEntry entry;
StaticLocalVariable var;

View File

@@ -131,7 +131,8 @@ abstract class TranslatedCoreExpr extends TranslatedExpr {
}
class TranslatedConditionValue extends TranslatedCoreExpr, ConditionContext,
TTranslatedConditionValue {
TTranslatedConditionValue
{
TranslatedConditionValue() { this = TTranslatedConditionValue(expr) }
override TranslatedElement getChild(int id) { id = 0 and result = this.getCondition() }
@@ -326,7 +327,8 @@ class TranslatedLoad extends TranslatedValueCategoryAdjustment, TTranslatedLoad
* from the AST.
*/
class TranslatedSyntheticTemporaryObject extends TranslatedValueCategoryAdjustment,
TTranslatedSyntheticTemporaryObject {
TTranslatedSyntheticTemporaryObject
{
TranslatedSyntheticTemporaryObject() { this = TTranslatedSyntheticTemporaryObject(expr) }
override string toString() { result = "Temporary materialization of " + expr.toString() }
@@ -2302,7 +2304,8 @@ class TranslatedBinaryConditionalExpr extends TranslatedConditionalExpr {
* its initializer.
*/
class TranslatedTemporaryObjectExpr extends TranslatedNonConstantExpr,
TranslatedVariableInitialization {
TranslatedVariableInitialization
{
override TemporaryObjectExpr expr;
final override predicate hasTempVariable(TempVariableTag tag, CppType type) {

View File

@@ -566,7 +566,8 @@ private TranslatedConstructorInitList getTranslatedConstructorInitList(Function
* instances for constructors can actually contain initializers.
*/
class TranslatedConstructorInitList extends TranslatedElement, InitializationContext,
TTranslatedConstructorInitList {
TTranslatedConstructorInitList
{
Function func;
TranslatedConstructorInitList() { this = TTranslatedConstructorInitList(func) }
@@ -637,7 +638,8 @@ private TranslatedDestructorDestructionList getTranslatedDestructorDestructionLi
* destructions.
*/
class TranslatedDestructorDestructionList extends TranslatedElement,
TTranslatedDestructorDestructionList {
TTranslatedDestructorDestructionList
{
Function func;
TranslatedDestructorDestructionList() { this = TTranslatedDestructorDestructionList(func) }

View File

@@ -9,7 +9,8 @@ private import InstructionTag
private import semmle.code.cpp.ir.internal.IRUtilities
class TranslatedGlobalOrNamespaceVarInit extends TranslatedRootElement,
TTranslatedGlobalOrNamespaceVarInit, InitializationContext {
TTranslatedGlobalOrNamespaceVarInit, InitializationContext
{
GlobalOrNamespaceVariable var;
TranslatedGlobalOrNamespaceVarInit() { this = TTranslatedGlobalOrNamespaceVarInit(var) }

View File

@@ -440,7 +440,8 @@ class TranslatedStringLiteralInitialization extends TranslatedDirectInitializati
}
class TranslatedConstructorInitialization extends TranslatedDirectInitialization,
StructorCallContext {
StructorCallContext
{
override ConstructorCall expr;
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -528,7 +529,8 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
* explicit element in an initializer list.
*/
class TranslatedExplicitFieldInitialization extends TranslatedFieldInitialization,
InitializationContext, TTranslatedExplicitFieldInitialization {
InitializationContext, TTranslatedExplicitFieldInitialization
{
Expr expr;
TranslatedExplicitFieldInitialization() {
@@ -565,7 +567,8 @@ private string getZeroValue(Type type) {
* corresponding element in the initializer list.
*/
class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
TTranslatedFieldValueInitialization {
TTranslatedFieldValueInitialization
{
TranslatedFieldValueInitialization() { this = TTranslatedFieldValueInitialization(ast, field) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -700,7 +703,8 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
* an explicit element in an initializer list.
*/
class TranslatedExplicitElementInitialization extends TranslatedElementInitialization,
TTranslatedExplicitElementInitialization, InitializationContext {
TTranslatedExplicitElementInitialization, InitializationContext
{
int elementIndex;
TranslatedExplicitElementInitialization() {
@@ -737,7 +741,8 @@ class TranslatedExplicitElementInitialization extends TranslatedElementInitializ
* elements without corresponding elements in the initializer list.
*/
class TranslatedElementValueInitialization extends TranslatedElementInitialization,
TTranslatedElementValueInitialization {
TTranslatedElementValueInitialization
{
int elementIndex;
int elementCount;
@@ -881,7 +886,8 @@ abstract class TranslatedBaseStructorCall extends TranslatedStructorCallFromStru
* Represents a call to a delegating or base class constructor from within a constructor.
*/
abstract class TranslatedConstructorCallFromConstructor extends TranslatedStructorCallFromStructor,
TTranslatedConstructorBaseInit {
TTranslatedConstructorBaseInit
{
TranslatedConstructorCallFromConstructor() { this = TTranslatedConstructorBaseInit(call) }
}
@@ -917,7 +923,8 @@ class TranslatedConstructorDelegationInit extends TranslatedConstructorCallFromC
* derived class constructor
*/
class TranslatedConstructorBaseInit extends TranslatedConstructorCallFromConstructor,
TranslatedBaseStructorCall {
TranslatedBaseStructorCall
{
TranslatedConstructorBaseInit() { not call instanceof ConstructorDelegationInit }
final override string toString() { result = "construct base: " + call.toString() }
@@ -934,7 +941,8 @@ TranslatedDestructorBaseDestruction getTranslatedDestructorBaseDestruction(
* derived class destructor.
*/
class TranslatedDestructorBaseDestruction extends TranslatedBaseStructorCall,
TTranslatedDestructorBaseDestruction {
TTranslatedDestructorBaseDestruction
{
TranslatedDestructorBaseDestruction() { this = TTranslatedDestructorBaseDestruction(call) }
final override string toString() { result = "destroy base: " + call.toString() }

View File

@@ -20,7 +20,8 @@ TranslatedMicrosoftTryExceptHandler getTranslatedMicrosoftTryExceptHandler(
}
class TranslatedMicrosoftTryExceptHandler extends TranslatedElement,
TTranslatedMicrosoftTryExceptHandler {
TTranslatedMicrosoftTryExceptHandler
{
MicrosoftTryExceptStmt tryExcept;
TranslatedMicrosoftTryExceptHandler() { this = TTranslatedMicrosoftTryExceptHandler(tryExcept) }

View File

@@ -87,22 +87,6 @@ class Operand extends TStageOperand {
this.getDefinitionOverlap() instanceof MustExactlyOverlap
}
/**
* DEPRECATED: renamed to `getUse`.
*
* Gets the `Instruction` that consumes this operand.
*/
deprecated final Instruction getUseInstruction() { result = this.getUse() }
/**
* DEPRECATED: use `getAnyDef` or `getDef`. The exact replacement for this
* predicate is `getAnyDef`, but most uses of this predicate should probably
* be replaced with `getDef`.
*
* Gets the `Instruction` whose result is the value of the operand.
*/
deprecated final Instruction getDefinitionInstruction() { result = this.getAnyDef() }
/**
* Gets the overlap relationship between the operand's definition and its use.
*/

View File

@@ -389,7 +389,8 @@ private class NewArrayAllocationExpr extends AllocationExpr, NewArrayExpr {
private module HeuristicAllocation {
/** A class that maps an `AllocationExpr` to an `HeuristicAllocationExpr`. */
private class HeuristicAllocationModeled extends HeuristicAllocationExpr instanceof AllocationExpr {
private class HeuristicAllocationModeled extends HeuristicAllocationExpr instanceof AllocationExpr
{
override Expr getSizeExpr() { result = AllocationExpr.super.getSizeExpr() }
override int getSizeMult() { result = AllocationExpr.super.getSizeMult() }
@@ -406,7 +407,8 @@ private module HeuristicAllocation {
}
/** A class that maps an `AllocationFunction` to an `HeuristicAllocationFunction`. */
private class HeuristicAllocationFunctionModeled extends HeuristicAllocationFunction instanceof AllocationFunction {
private class HeuristicAllocationFunctionModeled extends HeuristicAllocationFunction instanceof AllocationFunction
{
override int getSizeArg() { result = AllocationFunction.super.getSizeArg() }
override int getSizeMult() { result = AllocationFunction.super.getSizeMult() }
@@ -430,7 +432,8 @@ private module HeuristicAllocation {
* 2. The function must return a pointer type
* 3. There must be a unique parameter of unsigned integral type.
*/
private class HeuristicAllocationFunctionByName extends HeuristicAllocationFunction instanceof Function {
private class HeuristicAllocationFunctionByName extends HeuristicAllocationFunction instanceof Function
{
int sizeArg;
HeuristicAllocationFunctionByName() {

View File

@@ -7,7 +7,8 @@ import semmle.code.cpp.models.interfaces.FlowSource
* The standard functions `getdelim`, `getwdelim` and the glibc variant `__getdelim`.
*/
private class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectFunction,
RemoteFlowSourceFunction {
RemoteFlowSourceFunction
{
GetDelimFunction() { this.hasGlobalName(["getdelim", "getwdelim", "__getdelim"]) }
override predicate hasTaintFlow(FunctionInput i, FunctionOutput o) {

View File

@@ -14,7 +14,8 @@ import semmle.code.cpp.models.interfaces.FlowSource
* The standard functions `fgets` and `fgetws`.
*/
private class FgetsFunction extends DataFlowFunction, TaintFunction, ArrayFunction, AliasFunction,
SideEffectFunction, RemoteFlowSourceFunction {
SideEffectFunction, RemoteFlowSourceFunction
{
FgetsFunction() {
// fgets(str, num, stream)
// fgetws(wstr, num, stream)
@@ -69,7 +70,8 @@ private class FgetsFunction extends DataFlowFunction, TaintFunction, ArrayFuncti
* The standard functions `gets`.
*/
private class GetsFunction extends DataFlowFunction, ArrayFunction, AliasFunction,
SideEffectFunction, LocalFlowSourceFunction {
SideEffectFunction, LocalFlowSourceFunction
{
GetsFunction() {
// gets(str)
this.hasGlobalOrStdOrBslName("gets")

View File

@@ -7,7 +7,8 @@ import semmle.code.cpp.models.interfaces.SideEffect
* The standard function templates `std::move` and `std::forward`.
*/
private class IdentityFunction extends DataFlowFunction, SideEffectFunction, AliasFunction,
FunctionTemplateInstantiation {
FunctionTemplateInstantiation
{
IdentityFunction() { this.hasQualifiedName("std", ["move", "forward"]) }
override predicate hasOnlySpecificReadSideEffects() { any() }

View File

@@ -121,7 +121,8 @@ class IteratorCrementNonMemberOperator extends Operator {
}
private class IteratorCrementNonMemberOperatorModel extends IteratorCrementNonMemberOperator,
DataFlowFunction {
DataFlowFunction
{
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
input = getIteratorArgumentInput(this, 0) and
output.isReturnValue()
@@ -143,7 +144,8 @@ class IteratorCrementMemberOperator extends MemberFunction {
}
private class IteratorCrementMemberOperatorModel extends IteratorCrementMemberOperator,
DataFlowFunction, TaintFunction {
DataFlowFunction, TaintFunction
{
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierAddress() and
output.isReturnValue()
@@ -204,7 +206,8 @@ class IteratorBinaryArithmeticMemberOperator extends MemberFunction {
}
private class IteratorBinaryArithmeticMemberOperatorModel extends IteratorBinaryArithmeticMemberOperator,
TaintFunction {
TaintFunction
{
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
output.isReturnValue()
@@ -258,7 +261,8 @@ class IteratorAssignArithmeticNonMemberOperator extends Operator {
}
private class IteratorAssignArithmeticNonMemberOperatorModel extends IteratorAssignArithmeticNonMemberOperator,
DataFlowFunction, TaintFunction {
DataFlowFunction, TaintFunction
{
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and
output.isReturnValue()
@@ -289,7 +293,8 @@ class IteratorAssignArithmeticMemberOperator extends MemberFunction {
}
private class IteratorAssignArithmeticMemberOperatorModel extends IteratorAssignArithmeticMemberOperator,
DataFlowFunction, TaintFunction {
DataFlowFunction, TaintFunction
{
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierAddress() and
output.isReturnValue()
@@ -325,7 +330,8 @@ class IteratorAssignArithmeticOperator extends Function {
* non-member and member versions, use `IteratorPointerDereferenceOperator`.
*/
class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunction,
IteratorReferenceFunction {
IteratorReferenceFunction
{
IteratorPointerDereferenceMemberOperator() {
this.getClassAndName("operator*") instanceof Iterator
}
@@ -353,7 +359,8 @@ class IteratorPointerDereferenceNonMemberOperator extends Operator, IteratorRefe
}
private class IteratorPointerDereferenceNonMemberOperatorModel extends IteratorPointerDereferenceNonMemberOperator,
TaintFunction {
TaintFunction
{
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = getIteratorArgumentInput(this, 0) and
output.isReturnValue()
@@ -389,7 +396,8 @@ private class IteratorFieldMemberOperator extends Operator, TaintFunction {
* An `operator[]` member function of an iterator class.
*/
private class IteratorArrayMemberOperator extends MemberFunction, TaintFunction,
IteratorReferenceFunction {
IteratorReferenceFunction
{
IteratorArrayMemberOperator() { this.getClassAndName("operator[]") instanceof Iterator }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -418,7 +426,8 @@ class IteratorAssignmentMemberOperator extends MemberFunction {
* `operator*` and use their own `operator=` to assign to the container.
*/
private class IteratorAssignmentMemberOperatorModel extends IteratorAssignmentMemberOperator,
TaintFunction {
TaintFunction
{
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(0) and
output.isQualifierObject()

View File

@@ -15,7 +15,8 @@ import semmle.code.cpp.models.interfaces.Taint
* `__builtin___memcpy_chk`.
*/
private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffectFunction,
AliasFunction {
AliasFunction
{
MemcpyFunction() {
// memcpy(dest, src, num)
// memmove(dest, src, num)

View File

@@ -13,7 +13,8 @@ import semmle.code.cpp.models.interfaces.SideEffect
* The standard function `memset` and its assorted variants
*/
private class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunction,
SideEffectFunction {
SideEffectFunction
{
MemsetFunction() {
this.hasGlobalOrStdOrBslName("memset")
or

View File

@@ -8,7 +8,8 @@ import semmle.code.cpp.models.interfaces.SideEffect
* guaranteed to be side-effect free.
*/
private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunction,
SideEffectFunction {
SideEffectFunction
{
PureStrFunction() {
this.hasGlobalOrStdOrBslName([
atoi(), "strcasestr", "strchnul", "strchr", "strchrnul", "strstr", "strpbrk", "strrchr",
@@ -153,7 +154,8 @@ private class PureFunction extends TaintFunction, SideEffectFunction {
* evaluation is guaranteed to be side-effect free.
*/
private class PureMemFunction extends AliasFunction, ArrayFunction, TaintFunction,
SideEffectFunction {
SideEffectFunction
{
PureMemFunction() {
this.hasGlobalOrStdOrBslName([
"memchr", "__builtin_memchr", "memrchr", "rawmemchr", "memcmp", "__builtin_memcmp", "memmem"

View File

@@ -11,7 +11,8 @@ import semmle.code.cpp.models.interfaces.SideEffect
/** The function `recv` and its assorted variants */
private class Recv extends AliasFunction, ArrayFunction, SideEffectFunction,
RemoteFlowSourceFunction {
RemoteFlowSourceFunction
{
Recv() {
this.hasGlobalName([
"recv", // recv(socket, dest, len, flags)

View File

@@ -15,7 +15,8 @@ import semmle.code.cpp.models.interfaces.FlowSource
* The `scanf` family of functions.
*/
abstract private class ScanfFunctionModel extends ArrayFunction, TaintFunction, AliasFunction,
SideEffectFunction {
SideEffectFunction
{
override predicate hasArrayWithNullTerminator(int bufParam) {
bufParam = this.(ScanfFunction).getFormatParameterIndex()
}

View File

@@ -29,7 +29,8 @@ private class SmartPtr extends Class, PointerWrapper {
* - `std::weak_ptr<T>::operator*()`
*/
private class PointerUnwrapperFunction extends MemberFunction, TaintFunction, DataFlowFunction,
SideEffectFunction, AliasFunction {
SideEffectFunction, AliasFunction
{
PointerUnwrapperFunction() {
exists(PointerWrapper wrapper | wrapper.getAnUnwrapperFunction() = this)
}

View File

@@ -13,7 +13,8 @@ import semmle.code.cpp.models.interfaces.SideEffect
* The standard function `strset` and its assorted variants
*/
private class StrsetFunction extends ArrayFunction, DataFlowFunction, AliasFunction,
SideEffectFunction {
SideEffectFunction
{
StrsetFunction() {
hasGlobalName([
"strset", "_strset", "_strset_l", "_wcsset", "_wcsset_l", "_mbsset", "_mbsset_l",

View File

@@ -7,7 +7,8 @@ import semmle.code.cpp.models.interfaces.CommandExecution
* A function for running a command using a command interpreter.
*/
private class SystemFunction extends CommandExecutionFunction, ArrayFunction, AliasFunction,
SideEffectFunction {
SideEffectFunction
{
SystemFunction() {
hasGlobalOrStdName("system") or // system(command)
hasGlobalName("popen") or // popen(command, mode)

View File

@@ -40,12 +40,6 @@ class FunctionInput extends TFunctionInput {
*/
predicate isParameter(ParameterIndex index) { none() }
/**
* Holds if this is the input value of the parameter with index `index`.
* DEPRECATED: Use `isParameter(index)` instead.
*/
deprecated final predicate isInParameter(ParameterIndex index) { this.isParameter(index) }
/**
* Holds if this is the input value pointed to (through `ind` number of indirections) by a
* pointer parameter to a function, or the input value referred to by a reference parameter
@@ -84,16 +78,6 @@ class FunctionInput extends TFunctionInput {
*/
predicate isParameterDeref(ParameterIndex index) { this.isParameterDeref(index, 1) }
/**
* Holds if this is the input value pointed to by a pointer parameter to a function, or the input
* value referred to by a reference parameter to a function, where the parameter has index
* `index`.
* DEPRECATED: Use `isParameterDeref(index)` instead.
*/
deprecated final predicate isInParameterPointer(ParameterIndex index) {
this.isParameterDeref(index)
}
/**
* Holds if this is the input value pointed to by the `this` pointer of an instance member
* function.
@@ -124,13 +108,6 @@ class FunctionInput extends TFunctionInput {
*/
predicate isQualifierObject() { this.isQualifierObject(1) }
/**
* Holds if this is the input value pointed to by the `this` pointer of an instance member
* function.
* DEPRECATED: Use `isQualifierObject()` instead.
*/
deprecated final predicate isInQualifier() { this.isQualifierObject() }
/**
* Holds if this is the input value of the `this` pointer of an instance member function.
*
@@ -396,16 +373,6 @@ class FunctionOutput extends TFunctionOutput {
*/
predicate isParameterDeref(ParameterIndex i, int ind) { ind = 1 and this.isParameterDeref(i) }
/**
* Holds if this is the output value pointed to by a pointer parameter to a function, or the
* output value referred to by a reference parameter to a function, where the parameter has
* index `index`.
* DEPRECATED: Use `isParameterDeref(index)` instead.
*/
deprecated final predicate isOutParameterPointer(ParameterIndex index) {
this.isParameterDeref(index)
}
/**
* Holds if this is the output value pointed to by the `this` pointer of an instance member
* function.
@@ -436,13 +403,6 @@ class FunctionOutput extends TFunctionOutput {
*/
predicate isQualifierObject(int ind) { ind = 1 and this.isQualifierObject() }
/**
* Holds if this is the output value pointed to by the `this` pointer of an instance member
* function.
* DEPRECATED: Use `isQualifierObject()` instead.
*/
deprecated final predicate isOutQualifier() { this.isQualifierObject() }
/**
* Holds if this is the value returned by a function.
*
@@ -462,12 +422,6 @@ class FunctionOutput extends TFunctionOutput {
*/
predicate isReturnValue() { none() }
/**
* Holds if this is the value returned by a function.
* DEPRECATED: Use `isReturnValue()` instead.
*/
deprecated final predicate isOutReturnValue() { this.isReturnValue() }
/**
* Holds if this is the output value pointed to by the return value of a function, if the function
* returns a pointer, or the output value referred to by the return value of a function, if the
@@ -508,14 +462,6 @@ class FunctionOutput extends TFunctionOutput {
*/
predicate isReturnValueDeref(int ind) { ind = 1 and this.isReturnValueDeref() }
/**
* Holds if this is the output value pointed to by the return value of a function, if the function
* returns a pointer, or the output value referred to by the return value of a function, if the
* function returns a reference.
* DEPRECATED: Use `isReturnValueDeref()` instead.
*/
deprecated final predicate isOutReturnPointer() { this.isReturnValueDeref() }
/**
* Holds if `i >= 0` and `isParameterDeref(i, ind)` holds for this is the value, or
* if `i = -1` and `isQualifierObject(ind)` holds for this value.

View File

@@ -96,15 +96,6 @@ class RangeSsaDefinition extends ControlFlowNodeBase {
/** Whether this definition is a phi node for variable `v`. */
predicate isPhiNode(StackVariable v) { exists(RangeSsa x | x.phi_node(v, this)) }
/**
* DEPRECATED: Use isGuardPhi/4 instead
* If this definition is a phi node corresponding to a guard,
* then return the variable access and the guard.
*/
deprecated predicate isGuardPhi(VariableAccess va, Expr guard, boolean branch) {
guard_defn(va, guard, this, branch)
}
/**
* If this definition is a phi node corresponding to a guard,
* then return the variable guarded, the variable access and the guard.

View File

@@ -591,7 +591,8 @@ deprecated library class DataSensitiveExprCall extends DataSensitiveCallExpr, Ex
/** Call to a virtual function. */
deprecated library class DataSensitiveOverriddenFunctionCall extends DataSensitiveCallExpr,
FunctionCall {
FunctionCall
{
DataSensitiveOverriddenFunctionCall() {
exists(getTarget().(VirtualFunction).getAnOverridingFunction())
}

View File

@@ -1,3 +1,7 @@
## 0.5.4
No user-facing changes.
## 0.5.3
No user-facing changes.

View File

@@ -1,11 +1,11 @@
int write_default_config_bad() {
void write_default_config_bad() {
// BAD - this is world-writable so any user can overwrite the config
FILE* out = creat(OUTFILE, 0666);
fprintf(out, DEFAULT_CONFIG);
int out = creat(OUTFILE, 0666);
dprintf(out, DEFAULT_CONFIG);
}
int write_default_config_good() {
void write_default_config_good() {
// GOOD - this allows only the current user to modify the file
FILE* out = creat(OUTFILE, S_IWUSR | S_IRUSR);
fprintf(out, DEFAULT_CONFIG);
int out = creat(OUTFILE, S_IWUSR | S_IRUSR);
dprintf(out, DEFAULT_CONFIG);
}

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.5.3
lastReleaseVersion: 0.5.4

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 0.5.4-dev
version: 0.5.5-dev
groups:
- cpp
- queries

View File

@@ -61,14 +61,14 @@
| test.cpp:57:7:57:26 | definition of tmplClassProtoAndDef<T> |
| test.cpp:59:19:59:19 | definition of T |
| test.cpp:60:6:60:29 | declaration of tmplInstantiatedFunction |
| test.cpp:60:33:60:33 | definition of t |
| test.cpp:60:33:60:33 | definition of t |
| test.cpp:61:19:61:19 | definition of T |
| test.cpp:62:6:62:6 | definition of tmplInstantiatedFunction |
| test.cpp:62:6:62:6 | definition of tmplInstantiatedFunction |
| test.cpp:62:6:62:29 | definition of tmplInstantiatedFunction |
| test.cpp:62:33:62:33 | declaration of t |
| test.cpp:62:33:62:33 | definition of t |
| test.cpp:62:33:62:33 | definition of t |
| test.cpp:62:33:62:33 | definition of t |
| test.cpp:64:19:64:19 | definition of T |
| test.cpp:65:7:65:27 | declaration of tmplInstantiatedClass<T> |
| test.cpp:66:19:66:19 | definition of T |

View File

@@ -231,8 +231,8 @@ int test_unary(int a) {
int b = +a;
range(b); // $ range=<=11 range=>=3
int c = -a;
range(c);
range(b+c); // $ range=<=10 range="<=+ ...:a-1" range=">=- ...+1"
range(c); // $ range=<=-3 range=>=-11
range(b+c); // $ range=<=10 range="<=+ ...:a-1" range=">=- ...+1" range=>=-10
total += b+c;
range(total);
}
@@ -241,8 +241,8 @@ int test_unary(int a) {
int b = +a;
range(b); // $ range=<=11 range=>=0
int c = -a;
range(c);
range(b+c); // $ range=<=11 range="<=+ ...:a+0" range=">=- ...+0"
range(c); // $ range=<=0 range=>=-11
range(b+c); // $ range=<=11 range="<=+ ...:a+0" range=">=- ...+0" range=>=-11
total += b+c;
range(total);
}
@@ -251,7 +251,7 @@ int test_unary(int a) {
int b = +a;
range(b); // $ range=<=11 range=>=-7
int c = -a;
range(c);
range(c); // $ range=<=7 range=>=-11
range(b+c);
total += b+c;
range(total);
@@ -261,7 +261,7 @@ int test_unary(int a) {
int b = +a;
range(b); // $ range=<=1 range=>=-7
int c = -a;
range(c);
range(c); // $ range=<=7 range=>=-1
range(b+c);
total += b+c;
range(total);
@@ -271,8 +271,8 @@ int test_unary(int a) {
int b = +a;
range(b); // $ range=<=0 range=>=-7
int c = -a;
range(c);
range(b+c); // $ range="<=- ...+0" range=">=+ ...:a+0" range=>=-7
range(c); // $ range=<=7 range=>=0
range(b+c); // $ range="<=- ...+0" range=">=+ ...:a+0" range=>=-7 range=<=7
total += b+c;
range(total);
}
@@ -281,8 +281,8 @@ int test_unary(int a) {
int b = +a;
range(b); // $ range=<=-2 range=>=-7
int c = -a;
range(c);
range(b+c); // $ range="<=- ...-1" range=">=+ ...:a+1" range=>=-6
range(c); // $ range=<=7 range=>=2
range(b+c); // $ range="<=- ...-1" range=">=+ ...:a+1" range=>=-6 range=<=6
total += b+c;
range(total);
}
@@ -552,7 +552,7 @@ int test16(int x) {
range(x); // $ range=<=-1 range=>=0
return 1;
}
range(d); // $ range===3
range(d); // $ range=<=0 range=>=3 // Unreachable code
range(x); // $ range=<=-1 range=>=0
}
range(x); // $ range=>=0
@@ -997,3 +997,15 @@ void test_overflow() {
range(x + y); // $ range===-2147483393
}
}
void test_negate_unsigned(unsigned u) {
if(10 < u && u < 20) {
range<unsigned>(-u); // underflows
}
}
void test_negate_signed(int s) {
if(10 < s && s < 20) {
range<int>(-s); // $ range=<=-11 range=>=-19
}
}

View File

@@ -112,8 +112,6 @@
| isfromtemplateinstantiation.cpp:93:54:93:55 | { ... } | isfromtemplateinstantiation.cpp:93:7:93:7 | AnotherTemplateClass<int>::myMethod1(MyClassEnum) |
| isfromtemplateinstantiation.cpp:93:55:93:55 | return ... | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> |
| isfromtemplateinstantiation.cpp:93:55:93:55 | return ... | isfromtemplateinstantiation.cpp:93:7:93:7 | AnotherTemplateClass<int>::myMethod1(MyClassEnum) |
| isfromtemplateinstantiation.cpp:94:29:94:32 | definition of mce2 | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> |
| isfromtemplateinstantiation.cpp:94:29:94:32 | definition of mce2 | isfromtemplateinstantiation.cpp:97:52:97:52 | AnotherTemplateClass<int>::myMethod2(MyClassEnum) |
| isfromtemplateinstantiation.cpp:94:36:94:51 | MyClassEnumConst | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> |
| isfromtemplateinstantiation.cpp:94:36:94:51 | MyClassEnumConst | isfromtemplateinstantiation.cpp:97:52:97:52 | AnotherTemplateClass<int>::myMethod2(MyClassEnum) |
| isfromtemplateinstantiation.cpp:97:52:97:52 | AnotherTemplateClass<int>::myMethod2(MyClassEnum) | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> |
@@ -121,6 +119,8 @@
| isfromtemplateinstantiation.cpp:97:52:97:52 | definition of myMethod2 | isfromtemplateinstantiation.cpp:97:52:97:52 | AnotherTemplateClass<int>::myMethod2(MyClassEnum) |
| isfromtemplateinstantiation.cpp:97:74:97:77 | MyClassEnum mce2 | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> |
| isfromtemplateinstantiation.cpp:97:74:97:77 | MyClassEnum mce2 | isfromtemplateinstantiation.cpp:97:52:97:52 | AnotherTemplateClass<int>::myMethod2(MyClassEnum) |
| isfromtemplateinstantiation.cpp:97:74:97:77 | definition of mce2 | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> |
| isfromtemplateinstantiation.cpp:97:74:97:77 | definition of mce2 | isfromtemplateinstantiation.cpp:97:52:97:52 | AnotherTemplateClass<int>::myMethod2(MyClassEnum) |
| isfromtemplateinstantiation.cpp:98:1:99:1 | { ... } | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> |
| isfromtemplateinstantiation.cpp:98:1:99:1 | { ... } | isfromtemplateinstantiation.cpp:97:52:97:52 | AnotherTemplateClass<int>::myMethod2(MyClassEnum) |
| isfromtemplateinstantiation.cpp:99:1:99:1 | return ... | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> |

View File

@@ -95,9 +95,6 @@ isFromUninstantiatedTemplate
| isfromtemplateinstantiation.cpp:94:7:94:15 | declaration of myMethod2 | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<T> |
| isfromtemplateinstantiation.cpp:94:7:94:15 | declaration of myMethod2 | isfromtemplateinstantiation.cpp:97:25:97:60 | myMethod2 |
| isfromtemplateinstantiation.cpp:94:7:94:15 | declaration of myMethod2 | isfromtemplateinstantiation.cpp:97:52:97:52 | myMethod2 |
| isfromtemplateinstantiation.cpp:94:29:94:32 | declaration of mce2 | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<T> |
| isfromtemplateinstantiation.cpp:94:29:94:32 | declaration of mce2 | isfromtemplateinstantiation.cpp:97:25:97:60 | myMethod2 |
| isfromtemplateinstantiation.cpp:94:29:94:32 | declaration of mce2 | isfromtemplateinstantiation.cpp:97:52:97:52 | myMethod2 |
| isfromtemplateinstantiation.cpp:97:25:97:60 | definition of myMethod2 | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<T> |
| isfromtemplateinstantiation.cpp:97:25:97:60 | definition of myMethod2 | isfromtemplateinstantiation.cpp:97:25:97:60 | myMethod2 |
| isfromtemplateinstantiation.cpp:97:25:97:60 | definition of myMethod2 | isfromtemplateinstantiation.cpp:97:52:97:52 | myMethod2 |
@@ -110,6 +107,9 @@ isFromUninstantiatedTemplate
| isfromtemplateinstantiation.cpp:97:52:97:52 | myMethod2 | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<T> |
| isfromtemplateinstantiation.cpp:97:52:97:52 | myMethod2 | isfromtemplateinstantiation.cpp:97:25:97:60 | myMethod2 |
| isfromtemplateinstantiation.cpp:97:52:97:52 | myMethod2 | isfromtemplateinstantiation.cpp:97:52:97:52 | myMethod2 |
| isfromtemplateinstantiation.cpp:97:74:97:77 | declaration of mce2 | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<T> |
| isfromtemplateinstantiation.cpp:97:74:97:77 | declaration of mce2 | isfromtemplateinstantiation.cpp:97:25:97:60 | myMethod2 |
| isfromtemplateinstantiation.cpp:97:74:97:77 | declaration of mce2 | isfromtemplateinstantiation.cpp:97:52:97:52 | myMethod2 |
| isfromtemplateinstantiation.cpp:97:74:97:77 | definition of mce2 | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<T> |
| isfromtemplateinstantiation.cpp:97:74:97:77 | definition of mce2 | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<T> |
| isfromtemplateinstantiation.cpp:97:74:97:77 | definition of mce2 | isfromtemplateinstantiation.cpp:97:25:97:60 | myMethod2 |
@@ -433,6 +433,7 @@ isFromUninstantiatedTemplate
| isfromtemplateinstantiation.cpp:97:52:97:52 | myMethod2 | I | | Declaration | |
| isfromtemplateinstantiation.cpp:97:74:97:77 | definition of mce2 | | T | Definition | |
| isfromtemplateinstantiation.cpp:97:74:97:77 | definition of mce2 | | T | Definition | |
| isfromtemplateinstantiation.cpp:97:74:97:77 | definition of mce2 | I | | Definition | |
| isfromtemplateinstantiation.cpp:97:74:97:77 | mce2 | | T | Declaration | |
| isfromtemplateinstantiation.cpp:97:74:97:77 | mce2 | I | | Declaration | |
| isfromtemplateinstantiation.cpp:98:1:99:1 | { ... } | | T | Stmt | |

View File

@@ -241,7 +241,7 @@ namespace Semmle.Autobuild.Shared
SourceArchiveDir = RequireEnvironmentVariable(EnvVars.SourceArchiveDir(this.Options.Language));
DiagnosticsDir = RequireEnvironmentVariable(EnvVars.DiagnosticDir(this.Options.Language));
this.diagnostics = actions.CreateDiagnosticsWriter(Path.Combine(DiagnosticsDir, $"autobuilder-{DateTime.UtcNow:yyyyMMddHHmm}.jsonc"));
this.diagnostics = actions.CreateDiagnosticsWriter(Path.Combine(DiagnosticsDir, $"autobuilder-{DateTime.UtcNow:yyyyMMddHHmm}-{Environment.ProcessId}.jsonc"));
}
/// <summary>

View File

@@ -199,12 +199,8 @@ namespace Semmle.Autobuild.Shared
if (workingDirectory is not null)
pi.WorkingDirectory = workingDirectory;
// Environment variables can only be used when not redirecting stdout
if (!redirectStandardOutput)
{
if (environment is not null)
environment.ForEach(kvp => pi.Environment[kvp.Key] = kvp.Value);
}
environment?.ForEach(kvp => pi.Environment[kvp.Key] = kvp.Value);
return pi;
}

View File

@@ -1,3 +1,7 @@
## 1.4.4
No user-facing changes.
## 1.4.3
No user-facing changes.

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.4.3
lastReleaseVersion: 1.4.4

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-all
version: 1.4.4-dev
version: 1.4.5-dev
groups:
- csharp
- solorigate

View File

@@ -1,3 +1,7 @@
## 1.4.4
No user-facing changes.
## 1.4.3
No user-facing changes.

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.4.3
lastReleaseVersion: 1.4.4

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-queries
version: 1.4.4-dev
version: 1.4.5-dev
groups:
- csharp
- solorigate

View File

@@ -1,3 +1,14 @@
## 0.5.4
### Minor Analysis Improvements
* The query `cs/static-field-written-by-instance` is updated to handle properties.
* C# 11: Support for explicit interface member implementation of operators.
* The extraction of member modifiers has been generalized, which could lead to the extraction of more modifiers.
* C# 11: Added extractor and library support for `file` scoped types.
* C# 11: Added extractor support for `required` fields and properties.
* C# 11: Added library support for `checked` operators.
## 0.5.3
### Minor Analysis Improvements

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* C# 11: Added library support for `checked` operators.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* C# 11: Added extractor support for `required` fields and properties.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* C# 11: Added extractor and library support for `file` scoped types.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The extraction of member modifiers has been generalised, which could lead to the extraction of more modifiers.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* C# 11: Support for explicit interface member implementation of operators.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The query `cs/static-field-written-by-instance` is updated to handle properties.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The `unsafe` predicate for `Modifiable` has been extended to cover delegate return types and identify pointer like types at any nest level. This is relevant for `unsafe` declarations extracted from assemblies.

View File

@@ -0,0 +1,6 @@
---
category: minorAnalysis
---
* Deleted the deprecated `getPath` and `getFolder` predicates from the `XmlFile` class.
* Deleted the deprecated `getAssertionIndex`, and `getAssertedParameter` predicates from the `AssertMethod` class.
* Deleted the deprecated `OverridableMethod` and `OverridableAccessor` classes.

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Added support for merging two `PathGraph`s via disjoint union to allow results from multiple data flow computations in a single `path-problem` query.

View File

@@ -0,0 +1,10 @@
## 0.5.4
### Minor Analysis Improvements
* The query `cs/static-field-written-by-instance` is updated to handle properties.
* C# 11: Support for explicit interface member implementation of operators.
* The extraction of member modifiers has been generalized, which could lead to the extraction of more modifiers.
* C# 11: Added extractor and library support for `file` scoped types.
* C# 11: Added extractor support for `required` fields and properties.
* C# 11: Added library support for `checked` operators.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.5.3
lastReleaseVersion: 0.5.4

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-all
version: 0.5.4-dev
version: 0.5.5-dev
groups: csharp
dbscheme: semmlecode.csharp.dbscheme
extractor: csharp

View File

@@ -67,7 +67,8 @@ class MethodImplementation extends EntryPoint, @cil_method_implementation {
* destructors, operators, accessors and so on.
*/
class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowNode,
CustomModifierReceiver, Parameterizable, @cil_method {
CustomModifierReceiver, Parameterizable, @cil_method
{
/**
* Gets a method implementation, if any. Note that there can
* be several implementations in different assemblies.

View File

@@ -302,7 +302,8 @@ class SystemType extends ValueOrRefType {
* ```
*/
class FunctionPointerType extends Type, CustomModifierReceiver, Parameterizable,
@cil_function_pointer_type {
@cil_function_pointer_type
{
/** Gets the return type of this function pointer. */
Type getReturnType() { cil_function_pointer_return_type(this, result) }

View File

@@ -98,10 +98,21 @@ class Modifiable extends Declaration, @modifiable {
/** Holds if this declaration is `unsafe`. */
predicate isUnsafe() {
this.hasModifier("unsafe") or
this.(Parameterizable).getAParameter().getType() instanceof PointerType or
this.(Property).getType() instanceof PointerType or
this.(Callable).getReturnType() instanceof PointerType
this.hasModifier("unsafe")
or
exists(Type t, Type child |
t = this.(Parameterizable).getAParameter().getType() or
t = this.(Property).getType() or
t = this.(Callable).getReturnType() or
t = this.(DelegateType).getReturnType()
|
child = t.getAChild*() and
(
child instanceof PointerType
or
child instanceof FunctionPointerType
)
)
}
/** Holds if this declaration is `async`. */

View File

@@ -15,7 +15,8 @@ private import TypeRef
* (`Property`), or an indexer (`Indexer`).
*/
class DeclarationWithAccessors extends AssignableMember, Virtualizable, Attributable,
@declaration_with_accessors {
@declaration_with_accessors
{
/** Gets an accessor of this declaration. */
Accessor getAnAccessor() { result.getDeclaration() = this }
@@ -49,7 +50,8 @@ class DeclarationWithAccessors extends AssignableMember, Virtualizable, Attribut
* property (`Property`) or an indexer (`Indexer`).
*/
class DeclarationWithGetSetAccessors extends DeclarationWithAccessors, TopLevelExprParent,
@assignable_with_accessors {
@assignable_with_accessors
{
/** Gets the `get` accessor of this declaration, if any. */
Getter getGetter() { result = this.getAnAccessor() }

View File

@@ -90,7 +90,8 @@ class LocalScopeVariable extends Variable, @local_scope_variable {
* ```
*/
class Parameter extends DotNet::Parameter, LocalScopeVariable, Attributable, TopLevelExprParent,
@parameter {
@parameter
{
/**
* Gets the position of this parameter. For example, the position of `x` is
* 0 and the position of `y` is 1 in
@@ -376,7 +377,8 @@ class LocalConstant extends LocalVariable, @local_constant {
* ```
*/
class Field extends Variable, AssignableMember, Attributable, TopLevelExprParent, DotNet::Field,
@field {
@field
{
/**
* Gets the initial value of this field, if any. For example, the initial
* value of `F` on line 2 is `20` in

View File

@@ -108,20 +108,6 @@ class XmlFile extends XmlParent, File {
/** Gets the name of this XML file. */
override string getName() { result = File.super.getAbsolutePath() }
/**
* DEPRECATED: Use `getAbsolutePath()` instead.
*
* Gets the path of this XML file.
*/
deprecated string getPath() { result = this.getAbsolutePath() }
/**
* DEPRECATED: Use `getParentContainer().getAbsolutePath()` instead.
*
* Gets the path of the folder that contains this XML file.
*/
deprecated string getFolder() { result = this.getParentContainer().getAbsolutePath() }
/** Gets the encoding of this XML file. */
string getEncoding() { xmlEncoding(this, result) }

View File

@@ -37,26 +37,6 @@ abstract class AssertMethod extends Method {
/** Gets the index of a parameter being asserted. */
abstract int getAnAssertionIndex();
/**
* DEPRECATED: Use `getAnAssertionIndex()` instead.
*
* Gets the index of a parameter being asserted.
*/
deprecated final int getAssertionIndex() { result = this.getAnAssertionIndex() }
/** Gets the parameter at position `i` being asserted. */
final Parameter getAssertedParameter(int i) {
result = this.getParameter(i) and
i = this.getAnAssertionIndex()
}
/**
* DEPRECATED: Use `getAssertedParameter(_)` instead.
*
* Gets a parameter being asserted.
*/
deprecated final Parameter getAssertedParameter() { result = this.getAssertedParameter(_) }
/** Gets the failure type if the assertion fails for argument `i`, if any. */
abstract AssertionFailure getAssertionFailure(int i);
}
@@ -172,7 +152,8 @@ private predicate isDoesNotReturnIfAttributeParameter(Parameter p, boolean value
* A method with a parameter that is annotated with
* `System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute(false)`.
*/
class SystemDiagnosticsCodeAnalysisDoesNotReturnIfAnnotatedAssertTrueMethod extends BooleanAssertMethod {
class SystemDiagnosticsCodeAnalysisDoesNotReturnIfAnnotatedAssertTrueMethod extends BooleanAssertMethod
{
private int i_;
SystemDiagnosticsCodeAnalysisDoesNotReturnIfAnnotatedAssertTrueMethod() {
@@ -190,7 +171,8 @@ class SystemDiagnosticsCodeAnalysisDoesNotReturnIfAnnotatedAssertTrueMethod exte
* A method with a parameter that is annotated with
* `System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute(true)`.
*/
class SystemDiagnosticsCodeAnalysisDoesNotReturnIfAnnotatedAssertFalseMethod extends BooleanAssertMethod {
class SystemDiagnosticsCodeAnalysisDoesNotReturnIfAnnotatedAssertFalseMethod extends BooleanAssertMethod
{
private int i_;
SystemDiagnosticsCodeAnalysisDoesNotReturnIfAnnotatedAssertFalseMethod() {

View File

@@ -143,7 +143,8 @@ private class RecordConstructorFlow extends SummarizedCallable {
class RequiredSummaryComponentStack = Impl::Public::RequiredSummaryComponentStack;
private class RecordConstructorFlowRequiredSummaryComponentStack extends RequiredSummaryComponentStack {
private class RecordConstructorFlowRequiredSummaryComponentStack extends RequiredSummaryComponentStack
{
override predicate required(SummaryComponent head, SummaryComponentStack tail) {
exists(Property p |
recordConstructorFlow(_, _, p) and

View File

@@ -110,7 +110,8 @@ module Ssa {
/** A plain field or property. */
class PlainFieldOrPropSourceVariable extends FieldOrPropSourceVariable,
SsaImpl::TPlainFieldOrProp {
SsaImpl::TPlainFieldOrProp
{
override Callable getEnclosingCallable() { this = SsaImpl::TPlainFieldOrProp(result, _) }
override string toString() {
@@ -127,7 +128,8 @@ module Ssa {
/** A qualified field or property. */
class QualifiedFieldOrPropSourceVariable extends FieldOrPropSourceVariable,
SsaImpl::TQualifiedFieldOrProp {
SsaImpl::TQualifiedFieldOrProp
{
override Callable getEnclosingCallable() {
this = SsaImpl::TQualifiedFieldOrProp(result, _, _)
}

View File

@@ -243,3 +243,111 @@ module MakeWithState<StateConfigSig Config> implements DataFlowSig {
import Impl<C>
}
signature class PathNodeSig {
/** Gets a textual representation of this element. */
string toString();
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
);
/** Gets the underlying `Node`. */
Node getNode();
}
signature module PathGraphSig<PathNodeSig PathNode> {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
predicate edges(PathNode a, PathNode b);
/** Holds if `n` is a node in the graph of data flow path explanations. */
predicate nodes(PathNode n, string key, string val);
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out);
}
/**
* Constructs a `PathGraph` from two `PathGraph`s by disjoint union.
*/
module MergePathGraph<
PathNodeSig PathNode1, PathNodeSig PathNode2, PathGraphSig<PathNode1> Graph1,
PathGraphSig<PathNode2> Graph2>
{
private newtype TPathNode =
TPathNode1(PathNode1 p) or
TPathNode2(PathNode2 p)
/** A node in a graph of path explanations that is formed by disjoint union of the two given graphs. */
class PathNode extends TPathNode {
/** Gets this as a projection on the first given `PathGraph`. */
PathNode1 asPathNode1() { this = TPathNode1(result) }
/** Gets this as a projection on the second given `PathGraph`. */
PathNode2 asPathNode2() { this = TPathNode2(result) }
/** Gets a textual representation of this element. */
string toString() {
result = this.asPathNode1().toString() or
result = this.asPathNode2().toString()
}
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.asPathNode1().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) or
this.asPathNode2().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
Node getNode() {
result = this.asPathNode1().getNode() or
result = this.asPathNode2().getNode()
}
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
*/
module PathGraph implements PathGraphSig<PathNode> {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) {
Graph1::edges(a.asPathNode1(), b.asPathNode1()) or
Graph2::edges(a.asPathNode2(), b.asPathNode2())
}
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
Graph1::nodes(n.asPathNode1(), key, val) or
Graph2::nodes(n.asPathNode2(), key, val)
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Graph1::subpaths(arg.asPathNode1(), par.asPathNode1(), ret.asPathNode1(), out.asPathNode1()) or
Graph2::subpaths(arg.asPathNode2(), par.asPathNode2(), ret.asPathNode2(), out.asPathNode2())
}
}
}

View File

@@ -456,6 +456,7 @@ module Impl<FullStateConfigSig Config> {
* The Boolean `cc` records whether the node is reached through an
* argument in a call.
*/
pragma[assume_small_delta]
private predicate fwdFlow(NodeEx node, Cc cc) {
sourceNode(node, _) and
if hasSourceCallCtx() then cc = true else cc = false
@@ -3156,7 +3157,7 @@ module Impl<FullStateConfigSig Config> {
/**
* Provides the query predicates needed to include a graph in a path-problem query.
*/
module PathGraph {
module PathGraph implements PathGraphSig<PathNode> {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b }

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