mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
2.19.0 upgrade
This commit is contained in:
@@ -1,3 +1,27 @@
|
||||
## 2.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Deleted many deprecated taint-tracking configurations based on `TaintTracking::Configuration`.
|
||||
* Deleted many deprecated dataflow configurations based on `DataFlow::Configuration`.
|
||||
* Deleted the deprecated `hasQualifiedName` and `isDefined` predicates from the `Declaration` class, use `hasGlobalName` and `hasDefinition` respectively instead.
|
||||
* Deleted the `getFullSignature` predicate from the `Function` class, use `getIdentityString(Declaration)` from `semmle.code.cpp.Print` instead.
|
||||
* Deleted the deprecated `freeCall` predicate from `Alloc.qll`. Use `DeallocationExpr` instead.
|
||||
* Deleted the deprecated `explorationLimit` predicate from `DataFlow::Configuration`, use `FlowExploration<explorationLimit>` instead.
|
||||
* Deleted the deprecated `getFieldExpr` predicate from `ClassAggregateLiteral`, use `getAFieldExpr` instead.
|
||||
* Deleted the deprecated `getElementExpr` predicate from `ArrayOrVectorAggregateLiteral`, use `getAnElementExpr` instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a class `C11GenericExpr` to represent C11 generic selection expressions. The generic selection is represented as a `Conversion` on the expression that will be selected.
|
||||
* Added subclasses of `BuiltInOperations` for the `__is_scoped_enum`, `__is_trivially_equality_comparable`, and `__is_trivially_relocatable` builtin operations.
|
||||
* Added a subclass of `Expr` for `__datasizeof` expressions.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added a data flow model for `swap` member functions, which were previously modeled as taint tracking functions. This change improves the precision of queries where flow through `swap` member functions might affect the results.
|
||||
* Added a data flow model for `realloc`-like functions, which were previously modeled as a taint tracking functions. This change improves the precision of queries where flow through `realloc`-like functions might affect the results.
|
||||
|
||||
## 1.4.2
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
23
cpp/ql/lib/change-notes/released/2.0.0.md
Normal file
23
cpp/ql/lib/change-notes/released/2.0.0.md
Normal file
@@ -0,0 +1,23 @@
|
||||
## 2.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Deleted many deprecated taint-tracking configurations based on `TaintTracking::Configuration`.
|
||||
* Deleted many deprecated dataflow configurations based on `DataFlow::Configuration`.
|
||||
* Deleted the deprecated `hasQualifiedName` and `isDefined` predicates from the `Declaration` class, use `hasGlobalName` and `hasDefinition` respectively instead.
|
||||
* Deleted the `getFullSignature` predicate from the `Function` class, use `getIdentityString(Declaration)` from `semmle.code.cpp.Print` instead.
|
||||
* Deleted the deprecated `freeCall` predicate from `Alloc.qll`. Use `DeallocationExpr` instead.
|
||||
* Deleted the deprecated `explorationLimit` predicate from `DataFlow::Configuration`, use `FlowExploration<explorationLimit>` instead.
|
||||
* Deleted the deprecated `getFieldExpr` predicate from `ClassAggregateLiteral`, use `getAFieldExpr` instead.
|
||||
* Deleted the deprecated `getElementExpr` predicate from `ArrayOrVectorAggregateLiteral`, use `getAnElementExpr` instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a class `C11GenericExpr` to represent C11 generic selection expressions. The generic selection is represented as a `Conversion` on the expression that will be selected.
|
||||
* Added subclasses of `BuiltInOperations` for the `__is_scoped_enum`, `__is_trivially_equality_comparable`, and `__is_trivially_relocatable` builtin operations.
|
||||
* Added a subclass of `Expr` for `__datasizeof` expressions.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added a data flow model for `swap` member functions, which were previously modeled as taint tracking functions. This change improves the precision of queries where flow through `swap` member functions might affect the results.
|
||||
* Added a data flow model for `realloc`-like functions, which were previously modeled as a taint tracking functions. This change improves the precision of queries where flow through `realloc`-like functions might affect the results.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.4.2
|
||||
lastReleaseVersion: 2.0.0
|
||||
|
||||
@@ -36,16 +36,6 @@ module PrivateCleartextWrite {
|
||||
}
|
||||
}
|
||||
|
||||
deprecated class WriteConfig extends TaintTracking::Configuration {
|
||||
WriteConfig() { this = "Write configuration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
}
|
||||
|
||||
private module WriteConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 1.4.2
|
||||
version: 2.0.0
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -60,18 +60,6 @@ class Declaration extends Locatable, @declaration {
|
||||
*/
|
||||
string getQualifiedName() { result = underlyingElement(this).(Q::Declaration).getQualifiedName() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Prefer `hasGlobalName` or the 2-argument or 3-argument
|
||||
* `hasQualifiedName` predicates. To get the exact same results as this
|
||||
* predicate in all edge cases, use `getQualifiedName()`.
|
||||
*
|
||||
* Holds if this declaration has the fully-qualified name `qualifiedName`.
|
||||
* See `getQualifiedName`.
|
||||
*/
|
||||
deprecated predicate hasQualifiedName(string qualifiedName) {
|
||||
this.getQualifiedName() = qualifiedName
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this declaration has a fully-qualified name with a name-space
|
||||
* component of `namespaceQualifier`, a declaring type of `typeQualifier`,
|
||||
@@ -185,9 +173,6 @@ class Declaration extends Locatable, @declaration {
|
||||
/** Holds if the declaration has a definition. */
|
||||
predicate hasDefinition() { exists(this.getDefinition()) }
|
||||
|
||||
/** DEPRECATED: Use `hasDefinition` instead. */
|
||||
deprecated predicate isDefined() { this.hasDefinition() }
|
||||
|
||||
/** Gets the preferred location of this declaration, if any. */
|
||||
override Location getLocation() { none() }
|
||||
|
||||
|
||||
@@ -30,46 +30,6 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
|
||||
override string getName() { functions(underlyingElement(this), result, _) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getIdentityString(Declaration)` from `semmle.code.cpp.Print` instead.
|
||||
* Gets the full signature of this function, including return type, parameter
|
||||
* types, and template arguments.
|
||||
*
|
||||
* For example, in the following code:
|
||||
* ```
|
||||
* template<typename T> T min(T x, T y);
|
||||
* int z = min(5, 7);
|
||||
* ```
|
||||
* The full signature of the function called on the last line would be
|
||||
* `min<int>(int, int) -> int`, and the full signature of the uninstantiated
|
||||
* template on the first line would be `min<T>(T, T) -> T`.
|
||||
*/
|
||||
deprecated string getFullSignature() {
|
||||
exists(string name, string templateArgs, string args |
|
||||
result = name + templateArgs + args + " -> " + this.getType().toString() and
|
||||
name = this.getQualifiedName() and
|
||||
(
|
||||
if exists(this.getATemplateArgument())
|
||||
then
|
||||
templateArgs =
|
||||
"<" +
|
||||
concat(int i |
|
||||
exists(this.getTemplateArgument(i))
|
||||
|
|
||||
this.getTemplateArgument(i).toString(), ", " order by i
|
||||
) + ">"
|
||||
else templateArgs = ""
|
||||
) and
|
||||
args =
|
||||
"(" +
|
||||
concat(int i |
|
||||
exists(this.getParameter(i))
|
||||
|
|
||||
this.getParameter(i).getType().toString(), ", " order by i
|
||||
) + ")"
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a specifier of this function. */
|
||||
override Specifier getASpecifier() {
|
||||
funspecifiers(underlyingElement(this), unresolveElement(result)) or
|
||||
|
||||
@@ -286,9 +286,6 @@ abstract class BaseAstNode extends PrintAstNode {
|
||||
* Gets the AST represented by this node.
|
||||
*/
|
||||
final Locatable getAst() { result = ast }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated Locatable getAST() { result = this.getAst() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -385,6 +382,21 @@ class CastNode extends ConversionNode {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A node representing a `C11GenericExpr`.
|
||||
*/
|
||||
class C11GenericNode extends ConversionNode {
|
||||
C11GenericExpr generic;
|
||||
|
||||
C11GenericNode() { generic = conv }
|
||||
|
||||
override AstNode getChildInternal(int childIndex) {
|
||||
result = super.getChildInternal(childIndex - count(generic.getAChild()))
|
||||
or
|
||||
result.getAst() = generic.getChild(childIndex)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A node representing a `StmtExpr`.
|
||||
*/
|
||||
@@ -860,6 +872,15 @@ private predicate namedExprChildPredicates(Expr expr, Element ele, string pred)
|
||||
or
|
||||
expr.(BuiltInVarArgsStart).getLastNamedParameter() = ele and pred = "getLastNamedParameter()"
|
||||
or
|
||||
expr.(C11GenericExpr).getControllingExpr() = ele and pred = "getControllingExpr()"
|
||||
or
|
||||
exists(int n |
|
||||
expr.(C11GenericExpr).getAssociationType(n) = ele.(TypeName).getType() and
|
||||
pred = "getAssociationType(" + n + ")"
|
||||
or
|
||||
expr.(C11GenericExpr).getAssociationExpr(n) = ele and pred = "getAssociationExpr(" + n + ")"
|
||||
)
|
||||
or
|
||||
expr.(Call).getQualifier() = ele and pred = "getQualifier()"
|
||||
or
|
||||
exists(int n | expr.(Call).getArgument(n) = ele and pred = "getArgument(" + n.toString() + ")")
|
||||
|
||||
@@ -409,11 +409,18 @@ class LocalVariable extends LocalScopeVariable, @localvariable {
|
||||
exists(ConditionDeclExpr e | e.getVariable() = this and e.getEnclosingFunction() = result)
|
||||
or
|
||||
orphaned_variables(underlyingElement(this), unresolveElement(result))
|
||||
or
|
||||
coroutine_placeholder_variable(underlyingElement(this), _, unresolveElement(result))
|
||||
}
|
||||
|
||||
override predicate isStatic() {
|
||||
super.isStatic() or orphaned_variables(underlyingElement(this), _)
|
||||
}
|
||||
|
||||
override predicate isCompilerGenerated() {
|
||||
super.isCompilerGenerated() or
|
||||
coroutine_placeholder_variable(underlyingElement(this), _, _)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,15 +7,6 @@ import semmle.code.cpp.models.interfaces.Deallocation
|
||||
*/
|
||||
predicate freeFunction(Function f, int argNum) { argNum = f.(DeallocationFunction).getFreedArg() }
|
||||
|
||||
/**
|
||||
* A call to a library routine that frees memory.
|
||||
*
|
||||
* DEPRECATED: Use `DeallocationExpr` instead (this also includes `delete` expressions).
|
||||
*/
|
||||
deprecated predicate freeCall(FunctionCall fc, Expr arg) {
|
||||
arg = fc.(DeallocationExpr).getFreedExpr()
|
||||
}
|
||||
|
||||
/**
|
||||
* Is e some kind of allocation or deallocation (`new`, `alloc`, `realloc`, `delete`, `free` etc)?
|
||||
*/
|
||||
|
||||
@@ -168,14 +168,6 @@ abstract deprecated class Configuration extends string {
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `FlowExploration<explorationLimit>` instead.
|
||||
*
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
* measured in approximate number of interprocedural steps.
|
||||
*/
|
||||
deprecated int explorationLimit() { none() }
|
||||
|
||||
/**
|
||||
* Holds if hidden nodes should be included in the data flow graph.
|
||||
*
|
||||
|
||||
@@ -168,14 +168,6 @@ abstract deprecated class Configuration extends string {
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `FlowExploration<explorationLimit>` instead.
|
||||
*
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
* measured in approximate number of interprocedural steps.
|
||||
*/
|
||||
deprecated int explorationLimit() { none() }
|
||||
|
||||
/**
|
||||
* Holds if hidden nodes should be included in the data flow graph.
|
||||
*
|
||||
|
||||
@@ -168,14 +168,6 @@ abstract deprecated class Configuration extends string {
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `FlowExploration<explorationLimit>` instead.
|
||||
*
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
* measured in approximate number of interprocedural steps.
|
||||
*/
|
||||
deprecated int explorationLimit() { none() }
|
||||
|
||||
/**
|
||||
* Holds if hidden nodes should be included in the data flow graph.
|
||||
*
|
||||
|
||||
@@ -168,14 +168,6 @@ abstract deprecated class Configuration extends string {
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `FlowExploration<explorationLimit>` instead.
|
||||
*
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
* measured in approximate number of interprocedural steps.
|
||||
*/
|
||||
deprecated int explorationLimit() { none() }
|
||||
|
||||
/**
|
||||
* Holds if hidden nodes should be included in the data flow graph.
|
||||
*
|
||||
|
||||
@@ -168,14 +168,6 @@ abstract deprecated class Configuration extends string {
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `FlowExploration<explorationLimit>` instead.
|
||||
*
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
* measured in approximate number of interprocedural steps.
|
||||
*/
|
||||
deprecated int explorationLimit() { none() }
|
||||
|
||||
/**
|
||||
* Holds if hidden nodes should be included in the data flow graph.
|
||||
*
|
||||
|
||||
@@ -1885,3 +1885,59 @@ class BuiltInOperationIsWinInterface extends BuiltInOperation, @iswininterface {
|
||||
|
||||
override string getAPrimaryQlClass() { result = "BuiltInOperationIsWinInterface" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__is_trivially_equality_comparable` built-in operation.
|
||||
*
|
||||
* Returns `true` if comparing two objects of type `_Tp` is equivalent to
|
||||
* comparing their object representations.
|
||||
*
|
||||
* ```
|
||||
* template<typename _Tp>
|
||||
* struct is_trivially_equality_comparable
|
||||
* : public integral_constant<bool, __is_trivially_equality_comparable(_Tp)>
|
||||
* {};
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsTriviallyEqualityComparable extends BuiltInOperation,
|
||||
@istriviallyequalitycomparable
|
||||
{
|
||||
override string toString() { result = "__is_trivially_equality_comparable" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "BuiltInOperationIsTriviallyEqualityComparable" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__is_scoped_enum` built-in operation (used by some implementations
|
||||
* of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if a type is a scoped enum.
|
||||
* ```
|
||||
* template<typename _Tp>
|
||||
* constexpr bool is_scoped_enum = __is_scoped_enum(_Tp);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsScopedEnum extends BuiltInOperation, @isscopedenum {
|
||||
override string toString() { result = "__is_scoped_enum" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "BuiltInOperationIsScopedEnum" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__is_trivially_relocatable` built-in operation.
|
||||
*
|
||||
* Returns `true` if moving an object of type `_Tp` is equivalent to
|
||||
* copying the underlying bytes.
|
||||
*
|
||||
* ```
|
||||
* template<typename _Tp>
|
||||
* struct is_trivially_relocatable
|
||||
* : public integral_constant<bool, __is_trivially_relocatable(_Tp)>
|
||||
* {};
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsTriviallyRelocatable extends BuiltInOperation, @istriviallyrelocatable {
|
||||
override string toString() { result = "__is_trivially_relocatable" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "BuiltInOperationIsTriviallyRelocatable" }
|
||||
}
|
||||
|
||||
@@ -791,6 +791,53 @@ class AlignofTypeOperator extends AlignofOperator {
|
||||
override string toString() { result = "alignof(" + this.getTypeOperand().getName() + ")" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__datasizeof` expression (used by some implementations
|
||||
* of the `<type_traits>` header).
|
||||
*
|
||||
* The `__datasizeof` expression behaves identically to `sizeof` except
|
||||
* that the result ignores tail padding.
|
||||
*/
|
||||
class DatasizeofOperator extends Expr, @datasizeof {
|
||||
override int getPrecedence() { result = 16 }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__datasizeof` expression whose operand is an expression.
|
||||
*/
|
||||
class DatasizeofExprOperator extends DatasizeofOperator {
|
||||
DatasizeofExprOperator() { exists(this.getChild(0)) }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "DatasizeofExprOperator" }
|
||||
|
||||
/** Gets the contained expression. */
|
||||
Expr getExprOperand() { result = this.getChild(0) }
|
||||
|
||||
override string toString() { result = "__datasizeof(<expr>)" }
|
||||
|
||||
override predicate mayBeImpure() { this.getExprOperand().mayBeImpure() }
|
||||
|
||||
override predicate mayBeGloballyImpure() { this.getExprOperand().mayBeGloballyImpure() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__datasizeof` expression whose operand is a type name.
|
||||
*/
|
||||
class DatasizeofTypeOperator extends DatasizeofOperator {
|
||||
DatasizeofTypeOperator() { sizeof_bind(underlyingElement(this), _) }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "DatasizeofTypeOperator" }
|
||||
|
||||
/** Gets the contained type. */
|
||||
Type getTypeOperand() { sizeof_bind(underlyingElement(this), unresolveElement(result)) }
|
||||
|
||||
override string toString() { result = "__datasizeof(" + this.getTypeOperand().getName() + ")" }
|
||||
|
||||
override predicate mayBeImpure() { none() }
|
||||
|
||||
override predicate mayBeGloballyImpure() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ array to pointer conversion.
|
||||
*
|
||||
|
||||
@@ -304,6 +304,8 @@ class Expr extends StmtParent, @expr {
|
||||
e instanceof NoExceptExpr
|
||||
or
|
||||
e instanceof AlignofOperator
|
||||
or
|
||||
e instanceof DatasizeofOperator
|
||||
)
|
||||
or
|
||||
exists(Decltype d | d.getExpr() = this.getParentWithConversions*())
|
||||
@@ -630,6 +632,106 @@ class ParenthesisExpr extends Conversion, @parexpr {
|
||||
override string getAPrimaryQlClass() { result = "ParenthesisExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A node representing a C11 `_Generic` selection expression.
|
||||
*
|
||||
* For example:
|
||||
* ```
|
||||
* _Generic(e, int: "int", default: "unknown")
|
||||
* ```
|
||||
*/
|
||||
class C11GenericExpr extends Conversion, @c11_generic {
|
||||
int associationCount;
|
||||
|
||||
C11GenericExpr() { associationCount = (count(this.getAChild()) - 1) / 2 }
|
||||
|
||||
override string toString() { result = "_Generic" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "C11GenericExpr" }
|
||||
|
||||
/**
|
||||
* Gets the controlling expression of the generic selection.
|
||||
*
|
||||
* For example, for
|
||||
* ```
|
||||
* _Generic(e, int: "a", default: "b")
|
||||
* ```
|
||||
* the result is `e`.
|
||||
*/
|
||||
Expr getControllingExpr() { result = this.getChild(0) }
|
||||
|
||||
/**
|
||||
* Gets the type of the `n`th element in the association list of the generic selection.
|
||||
*
|
||||
* For example, for
|
||||
* ```
|
||||
* _Generic(e, int: "a", default: "b")
|
||||
* ```
|
||||
* the type of the 0th element is `int`. In the case of the default element the
|
||||
* type will an instance of `VoidType`.
|
||||
*/
|
||||
Type getAssociationType(int n) {
|
||||
n in [0 .. associationCount - 1] and
|
||||
result = this.getChild(n * 2 + 1).(TypeName).getType()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of an element in the association list of the generic selection.
|
||||
*/
|
||||
Type getAnAssociationType() { result = this.getAssociationType(_) }
|
||||
|
||||
/**
|
||||
* Gets the expression of the `n`th element in the association list of
|
||||
* the generic selection.
|
||||
*
|
||||
* For example, for
|
||||
* ```
|
||||
* _Generic(e, int: "a", default: "b")
|
||||
* ```
|
||||
* the expression for 0th element is `"a"`, and the expression for the
|
||||
* 1st element is `"b"`. For the selected expression, this predicate
|
||||
* will yield a `ReuseExpr`, such that
|
||||
* ```
|
||||
* this.getAssociationExpr(n).(ReuseExpr).getReusedExpr() = this.getExpr()
|
||||
* ```
|
||||
*/
|
||||
Expr getAssociationExpr(int n) {
|
||||
n in [0 .. associationCount - 1] and
|
||||
result = this.getChild(n * 2 + 2)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the expression of an element in the association list of the generic selection.
|
||||
*/
|
||||
Expr getAnAssociationExpr() { result = this.getAssociationExpr(_) }
|
||||
|
||||
/**
|
||||
* Holds if the `n`th element of the association list of the generic selection is the
|
||||
* default element.
|
||||
*
|
||||
* For example, for
|
||||
* ```
|
||||
* _Generic(e, int: "a", default: "b")
|
||||
* ```
|
||||
* this holds for 1.
|
||||
*/
|
||||
predicate isDefaultAssociation(int n) { this.getAssociationType(n) instanceof VoidType }
|
||||
|
||||
/**
|
||||
* Holds if the `n`th element of the association list of the generic selection is the
|
||||
* one whose expression was selected.
|
||||
*
|
||||
* For example, with `e` of type `int` and
|
||||
* ```
|
||||
* _Generic(e, int: "a", default: "b")
|
||||
* ```
|
||||
* this holds for 0.
|
||||
*/
|
||||
predicate isSelectedAssociation(int n) {
|
||||
this.getAssociationExpr(n).(ReuseExpr).getReusedExpr() = this.getExpr()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ expression that could not be resolved, or that can no longer be
|
||||
* represented due to a database upgrade or downgrade.
|
||||
@@ -666,6 +768,8 @@ class AssumeExpr extends Expr, @assume {
|
||||
|
||||
/**
|
||||
* A C/C++ comma expression.
|
||||
*
|
||||
* For example:
|
||||
* ```
|
||||
* int c = compute1(), compute2(), resulting_value;
|
||||
* ```
|
||||
|
||||
@@ -195,17 +195,6 @@ class ClassAggregateLiteral extends AggregateLiteral {
|
||||
*/
|
||||
Expr getAFieldExpr(Field field) { result = this.getFieldExpr(field, _) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getAFieldExpr` instead.
|
||||
*
|
||||
* Gets the expression within the aggregate literal that is used to initialize
|
||||
* field `field`, if present.
|
||||
*
|
||||
* This predicate may have multiple results since a field can be initialized
|
||||
* multiple times in the same initializer.
|
||||
*/
|
||||
deprecated Expr getFieldExpr(Field field) { result = this.getFieldExpr(field, _) }
|
||||
|
||||
/**
|
||||
* Gets the expression within the aggregate literal that is used to initialize
|
||||
* field `field`, if present. The expression is the `position`'th entry in the
|
||||
@@ -300,17 +289,6 @@ class ArrayOrVectorAggregateLiteral extends AggregateLiteral {
|
||||
*/
|
||||
Expr getAnElementExpr(int elementIndex) { result = this.getElementExpr(elementIndex, _) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getAnElementExpr` instead.
|
||||
*
|
||||
* Gets the expression within the aggregate literal that is used to initialize
|
||||
* element `elementIndex`, if present.
|
||||
*
|
||||
* This predicate may have multiple results since an element can be initialized
|
||||
* multiple times in the same initializer.
|
||||
*/
|
||||
deprecated Expr getElementExpr(int elementIndex) { result = this.getElementExpr(elementIndex, _) }
|
||||
|
||||
/**
|
||||
* Gets the expression within the aggregate literal that is used to initialize
|
||||
* element `elementIndex`, if present. The expression is the `position`'th entry
|
||||
|
||||
@@ -168,14 +168,6 @@ abstract deprecated class Configuration extends string {
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `FlowExploration<explorationLimit>` instead.
|
||||
*
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
* measured in approximate number of interprocedural steps.
|
||||
*/
|
||||
deprecated int explorationLimit() { none() }
|
||||
|
||||
/**
|
||||
* Holds if hidden nodes should be included in the data flow graph.
|
||||
*
|
||||
|
||||
@@ -168,14 +168,6 @@ abstract deprecated class Configuration extends string {
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `FlowExploration<explorationLimit>` instead.
|
||||
*
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
* measured in approximate number of interprocedural steps.
|
||||
*/
|
||||
deprecated int explorationLimit() { none() }
|
||||
|
||||
/**
|
||||
* Holds if hidden nodes should be included in the data flow graph.
|
||||
*
|
||||
|
||||
@@ -168,14 +168,6 @@ abstract deprecated class Configuration extends string {
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `FlowExploration<explorationLimit>` instead.
|
||||
*
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
* measured in approximate number of interprocedural steps.
|
||||
*/
|
||||
deprecated int explorationLimit() { none() }
|
||||
|
||||
/**
|
||||
* Holds if hidden nodes should be included in the data flow graph.
|
||||
*
|
||||
|
||||
@@ -168,14 +168,6 @@ abstract deprecated class Configuration extends string {
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `FlowExploration<explorationLimit>` instead.
|
||||
*
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
* measured in approximate number of interprocedural steps.
|
||||
*/
|
||||
deprecated int explorationLimit() { none() }
|
||||
|
||||
/**
|
||||
* Holds if hidden nodes should be included in the data flow graph.
|
||||
*
|
||||
|
||||
@@ -50,9 +50,6 @@ abstract private class AbstractIRVariable extends TIRVariable {
|
||||
*/
|
||||
abstract Language::AST getAst();
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated Language::AST getAST() { result = this.getAst() }
|
||||
|
||||
/**
|
||||
* Gets an identifier string for the variable. This identifier is unique
|
||||
* within the function.
|
||||
@@ -96,9 +93,6 @@ class IRUserVariable extends AbstractIRVariable, TIRUserVariable {
|
||||
|
||||
final override Language::AST getAst() { result = var }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Language::AST getAST() { result = this.getAst() }
|
||||
|
||||
final override string getUniqueId() {
|
||||
result = this.getVariable().toString() + " " + this.getVariable().getLocation().toString()
|
||||
}
|
||||
@@ -163,9 +157,6 @@ abstract private class AbstractIRGeneratedVariable extends AbstractIRVariable {
|
||||
|
||||
final override Language::AST getAst() { result = ast }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Language::AST getAST() { result = this.getAst() }
|
||||
|
||||
override string toString() { result = this.getBaseString() + this.getLocationString() }
|
||||
|
||||
override string getUniqueId() { none() }
|
||||
|
||||
@@ -285,9 +285,6 @@ abstract private class MemoryLocation0 extends TMemoryLocation {
|
||||
predicate isAlwaysAllocatedOnStack() { none() }
|
||||
|
||||
final predicate canReuseSsa() { none() }
|
||||
|
||||
/** DEPRECATED: Alias for canReuseSsa */
|
||||
deprecated predicate canReuseSSA() { this.canReuseSsa() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -50,9 +50,6 @@ abstract private class AbstractIRVariable extends TIRVariable {
|
||||
*/
|
||||
abstract Language::AST getAst();
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated Language::AST getAST() { result = this.getAst() }
|
||||
|
||||
/**
|
||||
* Gets an identifier string for the variable. This identifier is unique
|
||||
* within the function.
|
||||
@@ -96,9 +93,6 @@ class IRUserVariable extends AbstractIRVariable, TIRUserVariable {
|
||||
|
||||
final override Language::AST getAst() { result = var }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Language::AST getAST() { result = this.getAst() }
|
||||
|
||||
final override string getUniqueId() {
|
||||
result = this.getVariable().toString() + " " + this.getVariable().getLocation().toString()
|
||||
}
|
||||
@@ -163,9 +157,6 @@ abstract private class AbstractIRGeneratedVariable extends AbstractIRVariable {
|
||||
|
||||
final override Language::AST getAst() { result = ast }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Language::AST getAST() { result = this.getAst() }
|
||||
|
||||
override string toString() { result = this.getBaseString() + this.getLocationString() }
|
||||
|
||||
override string getUniqueId() { none() }
|
||||
|
||||
@@ -216,9 +216,6 @@ abstract class TranslatedSideEffects extends TranslatedElement {
|
||||
|
||||
final override Locatable getAst() { result = this.getExpr() }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
final override Declaration getFunction() { result = getEnclosingDeclaration(this.getExpr()) }
|
||||
|
||||
final override TranslatedElement getChild(int i) {
|
||||
@@ -616,9 +613,6 @@ class TranslatedArgumentExprSideEffect extends TranslatedArgumentSideEffect,
|
||||
|
||||
final override Locatable getAst() { result = arg }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
final override Type getIndirectionType() {
|
||||
result = arg.getUnspecifiedType().(DerivedType).getBaseType()
|
||||
or
|
||||
@@ -651,9 +645,6 @@ class TranslatedStructorQualifierSideEffect extends TranslatedArgumentSideEffect
|
||||
|
||||
final override Locatable getAst() { result = call }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
final override Type getIndirectionType() { result = call.getTarget().getDeclaringType() }
|
||||
|
||||
final override string getArgString() { result = "this" }
|
||||
@@ -675,9 +666,6 @@ class TranslatedCallSideEffect extends TranslatedSideEffect, TTranslatedCallSide
|
||||
|
||||
override Locatable getAst() { result = expr }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
override Expr getPrimaryExpr() { result = expr }
|
||||
|
||||
override predicate sortOrder(int group, int indexInGroup) {
|
||||
@@ -716,9 +704,6 @@ class TranslatedAllocationSideEffect extends TranslatedSideEffect, TTranslatedAl
|
||||
|
||||
override Locatable getAst() { result = expr }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
override Expr getPrimaryExpr() { result = expr }
|
||||
|
||||
override predicate sortOrder(int group, int indexInGroup) {
|
||||
|
||||
@@ -29,9 +29,6 @@ abstract class TranslatedCondition extends TranslatedElement {
|
||||
|
||||
final override Locatable getAst() { result = expr }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
final ConditionContext getConditionContext() { result = this.getParent() }
|
||||
|
||||
final Expr getExpr() { result = expr }
|
||||
|
||||
@@ -45,9 +45,6 @@ abstract class TranslatedDeclarationEntry extends TranslatedElement, TTranslated
|
||||
final override string toString() { result = entry.toString() }
|
||||
|
||||
final override Locatable getAst() { result = entry.getAst() }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -248,9 +245,6 @@ class TranslatedStaticLocalVariableInitialization extends TranslatedElement,
|
||||
|
||||
final override Locatable getAst() { result = entry.getAst() }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
final override LocalVariable getVariable() { result = var }
|
||||
|
||||
final override Declaration getFunction() { result = var.getFunction() }
|
||||
@@ -277,9 +271,6 @@ class TranslatedConditionDecl extends TranslatedLocalVariableDeclaration, TTrans
|
||||
|
||||
override Locatable getAst() { result = conditionDeclExpr }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
override Declaration getFunction() { result = getEnclosingFunction(conditionDeclExpr) }
|
||||
|
||||
override LocalVariable getVariable() { result = conditionDeclExpr.getVariable() }
|
||||
|
||||
@@ -128,6 +128,9 @@ private predicate ignoreExprAndDescendants(Expr expr) {
|
||||
vaStartExpr.getLastNamedParameter().getFullyConverted() = expr
|
||||
)
|
||||
or
|
||||
// The children of C11 _Generic expressions are just surface syntax.
|
||||
exists(C11GenericExpr generic | generic.getAChild() = expr)
|
||||
or
|
||||
// Do not translate implicit destructor calls for unnamed temporary variables that are
|
||||
// conditionally constructed (until we have a mechanism for calling these only when the
|
||||
// temporary's constructor was run)
|
||||
@@ -432,6 +435,9 @@ predicate ignoreLoad(Expr expr) {
|
||||
// The load is duplicated from the right operand.
|
||||
isExtractorFrontendVersion65OrHigher() and expr instanceof CommaExpr
|
||||
or
|
||||
// The load is duplicated from the chosen expression.
|
||||
expr instanceof C11GenericExpr
|
||||
or
|
||||
expr.(PointerDereferenceExpr).getOperand().getFullyConverted().getType().getUnspecifiedType()
|
||||
instanceof FunctionPointerType
|
||||
or
|
||||
@@ -761,7 +767,10 @@ newtype TTranslatedElement =
|
||||
} or
|
||||
// A statement
|
||||
TTranslatedStmt(Stmt stmt) { translateStmt(stmt) } or
|
||||
// The `__except` block of a `__try __except` statement
|
||||
TTranslatedMicrosoftTryExceptHandler(MicrosoftTryExceptStmt stmt) or
|
||||
// The `__finally` block of a `__try __finally` statement
|
||||
TTranslatedMicrosoftTryFinallyHandler(MicrosoftTryFinallyStmt stmt) or
|
||||
// A function
|
||||
TTranslatedFunction(Function func) { translateFunction(func) } or
|
||||
// A constructor init list
|
||||
@@ -920,9 +929,6 @@ abstract class TranslatedElement extends TTranslatedElement {
|
||||
*/
|
||||
abstract Locatable getAst();
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated Locatable getAST() { result = this.getAst() }
|
||||
|
||||
/** Gets the location of this element. */
|
||||
Location getLocation() { result = this.getAst().getLocation() }
|
||||
|
||||
|
||||
@@ -893,7 +893,8 @@ class TranslatedTransparentConversion extends TranslatedTransparentExpr {
|
||||
(
|
||||
expr instanceof ParenthesisExpr or
|
||||
expr instanceof ReferenceDereferenceExpr or
|
||||
expr instanceof ReferenceToExpr
|
||||
expr instanceof ReferenceToExpr or
|
||||
expr instanceof C11GenericExpr
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -67,9 +67,6 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
|
||||
|
||||
final override Locatable getAst() { result = func }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
/**
|
||||
* Gets the function being translated.
|
||||
*/
|
||||
@@ -212,8 +209,13 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
|
||||
(
|
||||
// Only generate the `Unwind` instruction if there is any exception
|
||||
// handling present in the function.
|
||||
exists(TryStmt try | try.getEnclosingFunction() = func) or
|
||||
exists(TryOrMicrosoftTryStmt try | try.getEnclosingFunction() = func)
|
||||
or
|
||||
exists(ThrowExpr throw | throw.getEnclosingFunction() = func)
|
||||
or
|
||||
exists(FunctionCall call | call.getEnclosingFunction() = func |
|
||||
getTranslatedExpr(call).(TranslatedCallExpr).mayThrowException()
|
||||
)
|
||||
)
|
||||
or
|
||||
tag = AliasedUseTag() and
|
||||
@@ -483,9 +485,6 @@ class TranslatedThisParameter extends TranslatedParameter, TTranslatedThisParame
|
||||
|
||||
final override Locatable getAst() { result = func }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
final override Function getFunction() { result = func }
|
||||
|
||||
final override predicate hasIndirection() { any() }
|
||||
@@ -518,9 +517,6 @@ class TranslatedPositionalParameter extends TranslatedParameter, TTranslatedPara
|
||||
|
||||
final override Locatable getAst() { result = param }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
final override Function getFunction() {
|
||||
result = param.getFunction() or
|
||||
result = param.getCatchBlock().getEnclosingFunction()
|
||||
@@ -558,9 +554,6 @@ class TranslatedEllipsisParameter extends TranslatedParameter, TTranslatedEllips
|
||||
|
||||
final override Locatable getAst() { result = func }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
final override Function getFunction() { result = func }
|
||||
|
||||
final override predicate hasIndirection() { any() }
|
||||
@@ -597,9 +590,6 @@ class TranslatedConstructorInitList extends TranslatedElement, InitializationCon
|
||||
|
||||
override Locatable getAst() { result = func }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
exists(ConstructorFieldInit fieldInit |
|
||||
fieldInit = func.(Constructor).getInitializer(id) and
|
||||
@@ -677,9 +667,6 @@ class TranslatedDestructorDestructionList extends TranslatedElement,
|
||||
|
||||
override Locatable getAst() { result = func }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
exists(DestructorFieldDestruction fieldDestruction |
|
||||
fieldDestruction = func.(Destructor).getDestruction(id) and
|
||||
@@ -733,9 +720,6 @@ class TranslatedReadEffects extends TranslatedElement, TTranslatedReadEffects {
|
||||
|
||||
override Locatable getAst() { result = func }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
override Function getFunction() { result = func }
|
||||
|
||||
override string toString() { result = "read effects: " + func.toString() }
|
||||
@@ -839,9 +823,6 @@ class TranslatedThisReadEffect extends TranslatedReadEffect, TTranslatedThisRead
|
||||
|
||||
override Locatable getAst() { result = func }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
override Function getFunction() { result = func }
|
||||
|
||||
override string toString() { result = "read effect: this" }
|
||||
@@ -865,9 +846,6 @@ class TranslatedParameterReadEffect extends TranslatedReadEffect, TTranslatedPar
|
||||
|
||||
override Locatable getAst() { result = param }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
override string toString() { result = "read effect: " + param.toString() }
|
||||
|
||||
override Function getFunction() { result = param.getFunction() }
|
||||
|
||||
@@ -153,9 +153,6 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
|
||||
|
||||
final override Locatable getAst() { result = expr }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
/**
|
||||
* Gets the expression that is doing the initialization.
|
||||
*/
|
||||
@@ -528,9 +525,6 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
|
||||
|
||||
final override Locatable getAst() { result = ast }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
final override Declaration getFunction() {
|
||||
result = getEnclosingFunction(ast) or
|
||||
result = getEnclosingVariable(ast).(GlobalOrNamespaceVariable) or
|
||||
@@ -701,9 +695,6 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
|
||||
|
||||
final override Locatable getAst() { result = initList }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
final override Declaration getFunction() {
|
||||
result = getEnclosingFunction(initList)
|
||||
or
|
||||
@@ -912,9 +903,6 @@ abstract class TranslatedStructorCallFromStructor extends TranslatedElement, Str
|
||||
|
||||
final override Locatable getAst() { result = call }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
final override TranslatedElement getChild(int id) {
|
||||
id = 0 and
|
||||
result = this.getStructorCall()
|
||||
@@ -1058,9 +1046,6 @@ class TranslatedConstructorBareInit extends TranslatedElement, TTranslatedConstr
|
||||
|
||||
override Locatable getAst() { result = init }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
final override string toString() { result = "construct base (no constructor)" }
|
||||
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
|
||||
@@ -79,11 +79,6 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement,
|
||||
tag = TryExceptCompareOneBranch() and
|
||||
opcode instanceof Opcode::ConditionalBranch and
|
||||
resultType = getVoidType()
|
||||
or
|
||||
// unwind stack
|
||||
tag = UnwindTag() and
|
||||
opcode instanceof Opcode::Unwind and
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
|
||||
@@ -156,7 +151,7 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement,
|
||||
// TODO: This is not really correct. The semantics of `EXCEPTION_CONTINUE_EXECUTION` is that
|
||||
// we should continue execution at the point where the exception occurred. But we don't have
|
||||
// any instruction to model this behavior.
|
||||
result = this.getInstruction(UnwindTag())
|
||||
result = this.getExceptionSuccessorInstruction(any(GotoEdge edge))
|
||||
or
|
||||
kind instanceof FalseEdge and
|
||||
result = this.getInstruction(TryExceptGenerateZero())
|
||||
@@ -176,7 +171,7 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement,
|
||||
tag = TryExceptCompareZeroBranch() and
|
||||
(
|
||||
kind instanceof TrueEdge and
|
||||
result = this.getInstruction(UnwindTag())
|
||||
result = this.getExceptionSuccessorInstruction(any(GotoEdge edge))
|
||||
or
|
||||
kind instanceof FalseEdge and
|
||||
result = this.getInstruction(TryExceptGenerateOne())
|
||||
@@ -196,10 +191,6 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement,
|
||||
tag = TryExceptCompareOneBranch() and
|
||||
kind instanceof TrueEdge and
|
||||
result = this.getTranslatedHandler().getFirstInstruction(any(GotoEdge edge))
|
||||
or
|
||||
// Unwind -> Parent
|
||||
tag = UnwindTag() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
@@ -215,8 +206,6 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement,
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getTranslatedHandler().getALastInstruction()
|
||||
or
|
||||
result = this.getInstruction(UnwindTag())
|
||||
}
|
||||
|
||||
private TranslatedExpr getTranslatedCondition() {
|
||||
@@ -236,6 +225,68 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement,
|
||||
}
|
||||
|
||||
final override Function getFunction() { result = tryExcept.getEnclosingFunction() }
|
||||
|
||||
override Instruction getExceptionSuccessorInstruction(EdgeKind kind) {
|
||||
// A throw from within a `__except` block flows to the handler for the parent of
|
||||
// the `__try`.
|
||||
result = this.getParent().getParent().getExceptionSuccessorInstruction(kind)
|
||||
}
|
||||
}
|
||||
|
||||
TranslatedMicrosoftTryFinallyHandler getTranslatedMicrosoftTryFinallyHandler(
|
||||
MicrosoftTryFinallyStmt tryFinally
|
||||
) {
|
||||
result.getAst() = tryFinally.getFinally()
|
||||
}
|
||||
|
||||
class TranslatedMicrosoftTryFinallyHandler extends TranslatedElement,
|
||||
TTranslatedMicrosoftTryFinallyHandler
|
||||
{
|
||||
MicrosoftTryFinallyStmt tryFinally;
|
||||
|
||||
TranslatedMicrosoftTryFinallyHandler() {
|
||||
this = TTranslatedMicrosoftTryFinallyHandler(tryFinally)
|
||||
}
|
||||
|
||||
final override string toString() { result = tryFinally.toString() }
|
||||
|
||||
final override Locatable getAst() { result = tryFinally.getFinally() }
|
||||
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getTranslatedFinally().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getTranslatedFinally().getALastInstruction()
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getTranslatedFinally() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
id = 0 and
|
||||
result = this.getTranslatedFinally()
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Function getFunction() { result = tryFinally.getEnclosingFunction() }
|
||||
|
||||
private TranslatedStmt getTranslatedFinally() {
|
||||
result = getTranslatedStmt(tryFinally.getFinally())
|
||||
}
|
||||
|
||||
override Instruction getExceptionSuccessorInstruction(EdgeKind kind) {
|
||||
// A throw from within a `__finally` block flows to the handler for the parent of
|
||||
// the `__try`.
|
||||
result = this.getParent().getParent().getExceptionSuccessorInstruction(kind)
|
||||
}
|
||||
}
|
||||
|
||||
abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt {
|
||||
@@ -268,9 +319,6 @@ abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt {
|
||||
|
||||
final override Locatable getAst() { result = stmt }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
final override Function getFunction() { result = stmt.getEnclosingFunction() }
|
||||
}
|
||||
|
||||
@@ -586,7 +634,7 @@ class TranslatedNoValueReturnStmt extends TranslatedReturnStmt, TranslatedVariab
|
||||
/**
|
||||
* A C/C++ `try` statement, or a `__try __except` or `__try __finally` statement.
|
||||
*/
|
||||
private class TryOrMicrosoftTryStmt extends Stmt {
|
||||
class TryOrMicrosoftTryStmt extends Stmt {
|
||||
TryOrMicrosoftTryStmt() {
|
||||
this instanceof TryStmt or
|
||||
this instanceof MicrosoftTryStmt
|
||||
@@ -619,7 +667,9 @@ private class TryOrMicrosoftTryStmt extends Stmt {
|
||||
}
|
||||
|
||||
/** Gets the `finally` statement (usually a BlockStmt), if any. */
|
||||
Stmt getFinally() { result = this.(MicrosoftTryFinallyStmt).getFinally() }
|
||||
TranslatedElement getTranslatedFinally() {
|
||||
result = getTranslatedMicrosoftTryFinallyHandler(this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -689,11 +739,14 @@ class TranslatedTryStmt extends TranslatedStmt {
|
||||
|
||||
final override Instruction getExceptionSuccessorInstruction(EdgeKind kind) {
|
||||
result = this.getHandler(0).getFirstInstruction(kind)
|
||||
or
|
||||
not exists(this.getHandler(_)) and
|
||||
result = this.getFinally().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
private TranslatedElement getHandler(int index) { result = stmt.getTranslatedHandler(index) }
|
||||
|
||||
private TranslatedStmt getFinally() { result = getTranslatedStmt(stmt.getFinally()) }
|
||||
private TranslatedElement getFinally() { result = stmt.getTranslatedFinally() }
|
||||
|
||||
private TranslatedStmt getBody() { result = getTranslatedStmt(stmt.getStmt()) }
|
||||
}
|
||||
|
||||
@@ -50,9 +50,6 @@ abstract private class AbstractIRVariable extends TIRVariable {
|
||||
*/
|
||||
abstract Language::AST getAst();
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated Language::AST getAST() { result = this.getAst() }
|
||||
|
||||
/**
|
||||
* Gets an identifier string for the variable. This identifier is unique
|
||||
* within the function.
|
||||
@@ -96,9 +93,6 @@ class IRUserVariable extends AbstractIRVariable, TIRUserVariable {
|
||||
|
||||
final override Language::AST getAst() { result = var }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Language::AST getAST() { result = this.getAst() }
|
||||
|
||||
final override string getUniqueId() {
|
||||
result = this.getVariable().toString() + " " + this.getVariable().getLocation().toString()
|
||||
}
|
||||
@@ -163,9 +157,6 @@ abstract private class AbstractIRGeneratedVariable extends AbstractIRVariable {
|
||||
|
||||
final override Language::AST getAst() { result = ast }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Language::AST getAST() { result = this.getAst() }
|
||||
|
||||
override string toString() { result = this.getBaseString() + this.getLocationString() }
|
||||
|
||||
override string getUniqueId() { none() }
|
||||
|
||||
@@ -71,9 +71,6 @@ class MemoryLocation extends TMemoryLocation {
|
||||
final string getUniqueId() { result = var.getUniqueId() }
|
||||
|
||||
final predicate canReuseSsa() { canReuseSsaForVariable(var) }
|
||||
|
||||
/** DEPRECATED: Alias for canReuseSsa */
|
||||
deprecated predicate canReuseSSA() { this.canReuseSsa() }
|
||||
}
|
||||
|
||||
predicate canReuseSsaForOldResult(Instruction instr) { none() }
|
||||
|
||||
@@ -42,6 +42,7 @@ private import implementations.Accept
|
||||
private import implementations.Poll
|
||||
private import implementations.Select
|
||||
private import implementations.MySql
|
||||
private import implementations.NoexceptFunction
|
||||
private import implementations.ODBC
|
||||
private import implementations.SqLite3
|
||||
private import implementations.PostgreSql
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.models.interfaces.Allocation
|
||||
import semmle.code.cpp.models.interfaces.Taint
|
||||
import semmle.code.cpp.models.interfaces.DataFlow
|
||||
|
||||
/**
|
||||
* An allocation function (such as `realloc`) that has an argument for the size
|
||||
* in bytes, and an argument for an existing pointer that is to be reallocated.
|
||||
*/
|
||||
private class ReallocAllocationFunction extends AllocationFunction, TaintFunction {
|
||||
private class ReallocAllocationFunction extends AllocationFunction, DataFlowFunction {
|
||||
int sizeArg;
|
||||
int reallocArg;
|
||||
|
||||
@@ -44,7 +44,7 @@ private class ReallocAllocationFunction extends AllocationFunction, TaintFunctio
|
||||
|
||||
override int getReallocPtrArg() { result = reallocArg }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||
input.isParameterDeref(this.getReallocPtrArg()) and output.isReturnValueDeref()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,13 +9,14 @@ import semmle.code.cpp.models.interfaces.DataFlow
|
||||
import semmle.code.cpp.models.interfaces.Alias
|
||||
import semmle.code.cpp.models.interfaces.SideEffect
|
||||
import semmle.code.cpp.models.interfaces.Taint
|
||||
import semmle.code.cpp.models.interfaces.NonThrowing
|
||||
|
||||
/**
|
||||
* The standard functions `memcpy`, `memmove` and `bcopy`; and the gcc variant
|
||||
* `__builtin___memcpy_chk`.
|
||||
*/
|
||||
private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffectFunction,
|
||||
AliasFunction
|
||||
AliasFunction, NonThrowingFunction
|
||||
{
|
||||
MemcpyFunction() {
|
||||
// memcpy(dest, src, num)
|
||||
|
||||
@@ -8,9 +8,10 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
|
||||
import semmle.code.cpp.models.interfaces.DataFlow
|
||||
import semmle.code.cpp.models.interfaces.Alias
|
||||
import semmle.code.cpp.models.interfaces.SideEffect
|
||||
import semmle.code.cpp.models.interfaces.NonThrowing
|
||||
|
||||
private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, AliasFunction,
|
||||
SideEffectFunction
|
||||
SideEffectFunction, NonThrowingFunction
|
||||
{
|
||||
MemsetFunctionModel() {
|
||||
this.hasGlobalOrStdOrBslName("memset")
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import semmle.code.cpp.models.interfaces.NonThrowing
|
||||
|
||||
/**
|
||||
* A function that is annotated with a `noexcept` specifier (or the equivalent
|
||||
* `throw()` specifier) guaranteeing that the function can not throw exceptions.
|
||||
*
|
||||
* Note: The `throw` specifier was deprecated in C++11 and removed in C++17.
|
||||
*/
|
||||
class NoexceptFunction extends NonThrowingFunction {
|
||||
NoexceptFunction() { this.isNoExcept() or this.isNoThrow() }
|
||||
}
|
||||
@@ -8,11 +8,12 @@
|
||||
import semmle.code.cpp.models.interfaces.FormattingFunction
|
||||
import semmle.code.cpp.models.interfaces.Alias
|
||||
import semmle.code.cpp.models.interfaces.SideEffect
|
||||
import semmle.code.cpp.models.interfaces.NonThrowing
|
||||
|
||||
/**
|
||||
* The standard functions `printf`, `wprintf` and their glib variants.
|
||||
*/
|
||||
private class Printf extends FormattingFunction, AliasFunction {
|
||||
private class Printf extends FormattingFunction, AliasFunction, NonThrowingFunction {
|
||||
Printf() {
|
||||
this instanceof TopLevelFunction and
|
||||
(
|
||||
@@ -36,7 +37,7 @@ private class Printf extends FormattingFunction, AliasFunction {
|
||||
/**
|
||||
* The standard functions `fprintf`, `fwprintf` and their glib variants.
|
||||
*/
|
||||
private class Fprintf extends FormattingFunction {
|
||||
private class Fprintf extends FormattingFunction, NonThrowingFunction {
|
||||
Fprintf() {
|
||||
this instanceof TopLevelFunction and
|
||||
(
|
||||
@@ -54,7 +55,7 @@ private class Fprintf extends FormattingFunction {
|
||||
/**
|
||||
* The standard function `sprintf` and its Microsoft and glib variants.
|
||||
*/
|
||||
private class Sprintf extends FormattingFunction {
|
||||
private class Sprintf extends FormattingFunction, NonThrowingFunction {
|
||||
Sprintf() {
|
||||
this instanceof TopLevelFunction and
|
||||
(
|
||||
@@ -97,7 +98,7 @@ private class Sprintf extends FormattingFunction {
|
||||
/**
|
||||
* Implements `Snprintf`.
|
||||
*/
|
||||
private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction {
|
||||
private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, NonThrowingFunction {
|
||||
SnprintfImpl() {
|
||||
this instanceof TopLevelFunction and
|
||||
(
|
||||
@@ -204,7 +205,7 @@ private class StringCchPrintf extends FormattingFunction {
|
||||
/**
|
||||
* The standard function `syslog`.
|
||||
*/
|
||||
private class Syslog extends FormattingFunction {
|
||||
private class Syslog extends FormattingFunction, NonThrowingFunction {
|
||||
Syslog() {
|
||||
this instanceof TopLevelFunction and
|
||||
this.hasGlobalName("syslog") and
|
||||
|
||||
@@ -7,13 +7,16 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
|
||||
import semmle.code.cpp.models.interfaces.DataFlow
|
||||
import semmle.code.cpp.models.interfaces.Taint
|
||||
import semmle.code.cpp.models.interfaces.SideEffect
|
||||
import semmle.code.cpp.models.interfaces.NonThrowing
|
||||
|
||||
/**
|
||||
* The standard function `strcat` and its wide, sized, and Microsoft variants.
|
||||
*
|
||||
* Does not include `strlcat`, which is covered by `StrlcatFunction`
|
||||
*/
|
||||
class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, SideEffectFunction {
|
||||
class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, SideEffectFunction,
|
||||
NonThrowingFunction
|
||||
{
|
||||
StrcatFunction() {
|
||||
this.hasGlobalOrStdOrBslName([
|
||||
"strcat", // strcat(dst, src)
|
||||
|
||||
@@ -7,11 +7,14 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
|
||||
import semmle.code.cpp.models.interfaces.DataFlow
|
||||
import semmle.code.cpp.models.interfaces.Taint
|
||||
import semmle.code.cpp.models.interfaces.SideEffect
|
||||
import semmle.code.cpp.models.interfaces.NonThrowing
|
||||
|
||||
/**
|
||||
* The standard function `strcpy` and its wide, sized, and Microsoft variants.
|
||||
*/
|
||||
class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, SideEffectFunction {
|
||||
class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, SideEffectFunction,
|
||||
NonThrowingFunction
|
||||
{
|
||||
StrcpyFunction() {
|
||||
this.hasGlobalOrStdOrBslName([
|
||||
"strcpy", // strcpy(dst, src)
|
||||
|
||||
@@ -26,7 +26,7 @@ private class Swap extends DataFlowFunction {
|
||||
* obj1.swap(obj2)
|
||||
* ```
|
||||
*/
|
||||
private class MemberSwap extends TaintFunction, MemberFunction, AliasFunction {
|
||||
private class MemberSwap extends DataFlowFunction, MemberFunction, AliasFunction {
|
||||
MemberSwap() {
|
||||
this.hasName("swap") and
|
||||
this.getNumberOfParameters() = 1 and
|
||||
@@ -34,7 +34,7 @@ private class MemberSwap extends TaintFunction, MemberFunction, AliasFunction {
|
||||
this.getDeclaringType()
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||
input.isQualifierObject() and
|
||||
output.isParameterDeref(0)
|
||||
or
|
||||
|
||||
11
cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll
Normal file
11
cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Provides an abstract class for modeling functions that never throw.
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.Function
|
||||
import semmle.code.cpp.models.Models
|
||||
|
||||
/**
|
||||
* A function that is guaranteed to never throw.
|
||||
*/
|
||||
abstract class NonThrowingFunction extends Function { }
|
||||
@@ -19,6 +19,11 @@ abstract class BufferAccess extends Expr {
|
||||
//A buffer access must be reachable (not in dead code)
|
||||
reachable(this)
|
||||
}
|
||||
BufferAccess() {
|
||||
not this.isUnevaluated() and
|
||||
//A buffer access must be reachable (not in dead code)
|
||||
reachable(this)
|
||||
}
|
||||
|
||||
abstract string getName();
|
||||
|
||||
@@ -30,6 +35,8 @@ abstract class BufferAccess extends Expr {
|
||||
* - 1 = buffer range [0, getSize) is accessed entirely.
|
||||
* - 2 = buffer range [0, getSize) may be accessed partially or entirely.
|
||||
* - 3 = buffer is accessed at offset getSize - 1.
|
||||
* - 4 = buffer is accessed with null terminator read protections
|
||||
* (does not read past null terminator, regardless of access size)
|
||||
*/
|
||||
abstract Expr getBuffer(string bufferDesc, int accessType);
|
||||
|
||||
|
||||
@@ -353,22 +353,6 @@ module BoostorgAsio {
|
||||
}
|
||||
|
||||
//////////////////////// Dataflow /////////////////////
|
||||
/**
|
||||
* Abstract class for flows of protocol values to the first argument of a context
|
||||
* constructor.
|
||||
*/
|
||||
abstract deprecated class SslContextCallAbstractConfig extends DataFlow::Configuration {
|
||||
bindingset[this]
|
||||
SslContextCallAbstractConfig() { any() }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(ConstructorCall cc, SslContextClass c, Expr e | e = sink.asExpr() |
|
||||
c.getAContructorCall() = cc and
|
||||
cc.getArgument(0) = e
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Signature for flows of protocol values to the first argument of a context
|
||||
* constructor.
|
||||
@@ -402,20 +386,6 @@ module BoostorgAsio {
|
||||
import DataFlow::Global<C>
|
||||
}
|
||||
|
||||
/**
|
||||
* Any protocol value that flows to the first argument of a context constructor.
|
||||
*/
|
||||
deprecated class SslContextCallConfig extends SslContextCallAbstractConfig {
|
||||
SslContextCallConfig() { this = "SslContextCallConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists(Expr e | e = source.asExpr() |
|
||||
e.fromSource() and
|
||||
not e.getLocation().getFile().toString().matches("%/boost/asio/%")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Any protocol value that flows to the first argument of a context constructor.
|
||||
*/
|
||||
@@ -430,21 +400,6 @@ module BoostorgAsio {
|
||||
|
||||
module SslContextCallFlow = SslContextCallGlobal<SslContextCallConfig>;
|
||||
|
||||
/**
|
||||
* A banned protocol value that flows to the first argument of a context constructor.
|
||||
*/
|
||||
deprecated class SslContextCallBannedProtocolConfig extends SslContextCallAbstractConfig {
|
||||
SslContextCallBannedProtocolConfig() { this = "SslContextCallBannedProtocolConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists(Expr e | e = source.asExpr() |
|
||||
e.fromSource() and
|
||||
not e.getLocation().getFile().toString().matches("%/boost/asio/%") and
|
||||
isExprBannedBoostProtocol(e)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A banned protocol value that flows to the first argument of a context constructor.
|
||||
*/
|
||||
@@ -461,21 +416,6 @@ module BoostorgAsio {
|
||||
module SslContextCallBannedProtocolFlow =
|
||||
SslContextCallGlobal<SslContextCallBannedProtocolConfig>;
|
||||
|
||||
/**
|
||||
* A TLS 1.2 protocol value that flows to the first argument of a context constructor.
|
||||
*/
|
||||
deprecated class SslContextCallTls12ProtocolConfig extends SslContextCallAbstractConfig {
|
||||
SslContextCallTls12ProtocolConfig() { this = "SslContextCallTls12ProtocolConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists(Expr e | e = source.asExpr() |
|
||||
e.fromSource() and
|
||||
not e.getLocation().getFile().toString().matches("%/boost/asio/%") and
|
||||
isExprTls12BoostProtocol(e)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A TLS 1.2 protocol value that flows to the first argument of a context constructor.
|
||||
*/
|
||||
@@ -491,21 +431,6 @@ module BoostorgAsio {
|
||||
|
||||
module SslContextCallTls12ProtocolFlow = SslContextCallGlobal<SslContextCallTls12ProtocolConfig>;
|
||||
|
||||
/**
|
||||
* A TLS 1.3 protocol value that flows to the first argument of a context constructor.
|
||||
*/
|
||||
deprecated class SslContextCallTls13ProtocolConfig extends SslContextCallAbstractConfig {
|
||||
SslContextCallTls13ProtocolConfig() { this = "SslContextCallTls12ProtocolConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists(Expr e | e = source.asExpr() |
|
||||
e.fromSource() and
|
||||
not e.getLocation().getFile().toString().matches("%/boost/asio/%") and
|
||||
isExprTls13BoostProtocol(e)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A TLS 1.3 protocol value that flows to the first argument of a context constructor.
|
||||
*/
|
||||
@@ -521,21 +446,6 @@ module BoostorgAsio {
|
||||
|
||||
module SslContextCallTls13ProtocolFlow = SslContextCallGlobal<SslContextCallTls13ProtocolConfig>;
|
||||
|
||||
/**
|
||||
* A generic TLS protocol value that flows to the first argument of a context constructor.
|
||||
*/
|
||||
deprecated class SslContextCallTlsProtocolConfig extends SslContextCallAbstractConfig {
|
||||
SslContextCallTlsProtocolConfig() { this = "SslContextCallTlsProtocolConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists(Expr e | e = source.asExpr() |
|
||||
e.fromSource() and
|
||||
not e.getLocation().getFile().toString().matches("%/boost/asio/%") and
|
||||
isExprTlsBoostProtocol(e)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A generic TLS protocol value that flows to the first argument of a context constructor.
|
||||
*/
|
||||
@@ -551,30 +461,6 @@ module BoostorgAsio {
|
||||
|
||||
module SslContextCallTlsProtocolFlow = SslContextCallGlobal<SslContextCallTlsProtocolConfig>;
|
||||
|
||||
/**
|
||||
* A context constructor call that flows to a call to `SetOptions()`.
|
||||
*/
|
||||
deprecated class SslContextFlowsToSetOptionConfig extends DataFlow::Configuration {
|
||||
SslContextFlowsToSetOptionConfig() { this = "SslContextFlowsToSetOptionConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists(SslContextClass c, ConstructorCall cc |
|
||||
cc = source.asExpr() and
|
||||
c.getAContructorCall() = cc
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(FunctionCall fc, SslSetOptionsFunction f, Variable v, VariableAccess va |
|
||||
va = sink.asExpr()
|
||||
|
|
||||
f.getACallToThisFunction() = fc and
|
||||
v.getAnAccess() = va and
|
||||
va = fc.getQualifier()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A context constructor call that flows to a call to `SetOptions()`.
|
||||
*/
|
||||
@@ -599,28 +485,6 @@ module BoostorgAsio {
|
||||
|
||||
module SslContextFlowsToSetOptionFlow = DataFlow::Global<SslContextFlowsToSetOptionConfig>;
|
||||
|
||||
/**
|
||||
* An option value that flows to the first parameter of a call to `SetOptions()`.
|
||||
*/
|
||||
deprecated class SslOptionConfig extends DataFlow::Configuration {
|
||||
SslOptionConfig() { this = "SslOptionConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists(Expr e | e = source.asExpr() |
|
||||
e.fromSource() and
|
||||
not e.getLocation().getFile().toString().matches("%/boost/asio/%")
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(SslSetOptionsFunction f, FunctionCall call |
|
||||
sink.asExpr() = call.getArgument(0) and
|
||||
f.getACallToThisFunction() = call and
|
||||
not sink.getLocation().getFile().toString().matches("%/boost/asio/%")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An option value that flows to the first parameter of a call to `SetOptions()`.
|
||||
*/
|
||||
|
||||
@@ -384,11 +384,23 @@ function_return_type(
|
||||
*/
|
||||
coroutine(
|
||||
unique int function: @function ref,
|
||||
int traits: @type ref,
|
||||
int handle: @variable ref,
|
||||
int promise: @variable ref
|
||||
int traits: @type ref
|
||||
);
|
||||
|
||||
/*
|
||||
case @coroutine_placeholder_variable.kind of
|
||||
1 = @handle
|
||||
| 2 = @promise
|
||||
| 3 = @init_await_resume
|
||||
;
|
||||
*/
|
||||
|
||||
coroutine_placeholder_variable(
|
||||
unique int placeholder_variable: @variable ref,
|
||||
int kind: int ref,
|
||||
int function: @function ref
|
||||
)
|
||||
|
||||
/** The `new` function used for allocating the coroutine state, if any. */
|
||||
coroutine_new(
|
||||
unique int function: @function ref,
|
||||
@@ -829,22 +841,6 @@ variable_template_argument_value(
|
||||
int arg_value: @expr ref
|
||||
);
|
||||
|
||||
/*
|
||||
Fixed point types
|
||||
precision(1) = short, precision(2) = default, precision(3) = long
|
||||
is_unsigned(1) = unsigned is_unsigned(2) = signed
|
||||
is_fract_type(1) = declared with _Fract
|
||||
saturating(1) = declared with _Sat
|
||||
*/
|
||||
/* TODO
|
||||
fixedpointtypes(
|
||||
unique int id: @fixedpointtype,
|
||||
int precision: int ref,
|
||||
int is_unsigned: int ref,
|
||||
int is_fract_type: int ref,
|
||||
int saturating: int ref);
|
||||
*/
|
||||
|
||||
routinetypes(
|
||||
unique int id: @routinetype,
|
||||
int return_type: @type ref
|
||||
@@ -1210,6 +1206,7 @@ conversionkinds(
|
||||
| @reference_to
|
||||
| @ref_indirect
|
||||
| @temp_init
|
||||
| @c11_generic
|
||||
;
|
||||
|
||||
/*
|
||||
@@ -1788,6 +1785,11 @@ case @expr.kind of
|
||||
| 382 = @isvalidwinrttype
|
||||
| 383 = @iswinclass
|
||||
| 384 = @iswininterface
|
||||
| 385 = @istriviallyequalitycomparable
|
||||
| 386 = @isscopedenum
|
||||
| 387 = @istriviallyrelocatable
|
||||
| 388 = @datasizeof
|
||||
| 389 = @c11_generic
|
||||
;
|
||||
|
||||
@var_args_expr = @vastartexpr
|
||||
@@ -1901,6 +1903,9 @@ case @expr.kind of
|
||||
| @isvalidwinrttype
|
||||
| @iswinclass
|
||||
| @iswininterface
|
||||
| @istriviallyequalitycomparable
|
||||
| @isscopedenum
|
||||
| @istriviallyrelocatable
|
||||
;
|
||||
|
||||
new_allocated_type(
|
||||
@@ -1961,7 +1966,7 @@ uuidof_bind(
|
||||
int type_id: @type ref
|
||||
);
|
||||
|
||||
@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof;
|
||||
@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof;
|
||||
|
||||
sizeof_bind(
|
||||
unique int expr: @runtime_sizeof_or_alignof ref,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Expose C11 _Generics
|
||||
compatibility: backwards
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
description: Improve handling of coroutine placeholder variables
|
||||
compatibility: partial
|
||||
coroutine.rel: run upgrades.qlo new_coroutine
|
||||
coroutine_placeholder_variable.rel: run upgrades.qlo new_coroutine_placeholder_variable
|
||||
@@ -0,0 +1,19 @@
|
||||
class Function extends @function {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Type extends @type {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Variable extends @variable {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
query predicate new_coroutine(Function func, Type traits) { coroutine(func, traits, _, _) }
|
||||
|
||||
query predicate new_coroutine_placeholder_variable(Variable var, int kind, Function func) {
|
||||
coroutine(func, _, var, _) and kind = 1
|
||||
or
|
||||
coroutine(func, _, _, var) and kind = 2
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Add new builtin operations
|
||||
compatibility: backwards
|
||||
@@ -1,3 +1,11 @@
|
||||
## 1.2.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Removed false positives caused by buffer accesses in unreachable code.
|
||||
* Removed false positives caused by inconsistent type checking.
|
||||
* Add modeling of C functions that don't throw, thereby increasing the precision of the `cpp/incorrect-allocation-error-handling` ("Incorrect allocation-error handling") query. The query now produces additional true positives.
|
||||
|
||||
## 1.2.2
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -42,7 +42,9 @@ class BufferAccess extends ArrayExpr {
|
||||
not exists(Macro m |
|
||||
m.getName() = "strcmp" and
|
||||
m.getAnInvocation().getAnExpandedElement() = this
|
||||
)
|
||||
) and
|
||||
//A buffer access must be reachable (not in dead code)
|
||||
reachable(this)
|
||||
}
|
||||
|
||||
int bufferSize() { staticBuffer(this.getArrayBase(), _, result) }
|
||||
|
||||
@@ -205,20 +205,6 @@ class ChecksForLeapYearFunctionCall extends FunctionCall {
|
||||
ChecksForLeapYearFunctionCall() { this.getTarget() instanceof ChecksForLeapYearFunction }
|
||||
}
|
||||
|
||||
/**
|
||||
* Data flow configuration for finding a variable access that would flow into
|
||||
* a function call that includes an operation to check for leap year.
|
||||
*/
|
||||
deprecated class LeapYearCheckConfiguration extends DataFlow::Configuration {
|
||||
LeapYearCheckConfiguration() { this = "LeapYearCheckConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof VariableAccess }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(ChecksForLeapYearFunctionCall fc | sink.asExpr() = fc.getAnArgument())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data flow configuration for finding a variable access that would flow into
|
||||
* a function call that includes an operation to check for leap year.
|
||||
@@ -233,33 +219,6 @@ private module LeapYearCheckConfig implements DataFlow::ConfigSig {
|
||||
|
||||
module LeapYearCheckFlow = DataFlow::Global<LeapYearCheckConfig>;
|
||||
|
||||
/**
|
||||
* Data flow configuration for finding an operation with hardcoded 365 that will flow into
|
||||
* a `FILEINFO` field.
|
||||
*/
|
||||
deprecated class FiletimeYearArithmeticOperationCheckConfiguration extends DataFlow::Configuration {
|
||||
FiletimeYearArithmeticOperationCheckConfiguration() {
|
||||
this = "FiletimeYearArithmeticOperationCheckConfiguration"
|
||||
}
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists(Expr e, Operation op | e = source.asExpr() |
|
||||
op.getAChild*().getValue().toInt() = 365 and
|
||||
op.getAChild*() = e
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(StructLikeClass dds, FieldAccess fa, AssignExpr aexpr, Expr e | e = sink.asExpr() |
|
||||
dds instanceof PackedTimeType and
|
||||
fa.getQualifier().getUnderlyingType() = dds and
|
||||
fa.isModified() and
|
||||
aexpr.getAChild() = fa and
|
||||
aexpr.getChild(1).getAChild*() = e
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data flow configuration for finding an operation with hardcoded 365 that will flow into
|
||||
* a `FILEINFO` field.
|
||||
@@ -286,51 +245,6 @@ private module FiletimeYearArithmeticOperationCheckConfig implements DataFlow::C
|
||||
module FiletimeYearArithmeticOperationCheckFlow =
|
||||
DataFlow::Global<FiletimeYearArithmeticOperationCheckConfig>;
|
||||
|
||||
/**
|
||||
* Taint configuration for finding an operation with hardcoded 365 that will flow into any known date/time field.
|
||||
*/
|
||||
deprecated class PossibleYearArithmeticOperationCheckConfiguration extends TaintTracking::Configuration
|
||||
{
|
||||
PossibleYearArithmeticOperationCheckConfiguration() {
|
||||
this = "PossibleYearArithmeticOperationCheckConfiguration"
|
||||
}
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists(Operation op | op = source.asExpr() |
|
||||
op.getAChild*().getValue().toInt() = 365 and
|
||||
(
|
||||
not op.getParent() instanceof Expr or
|
||||
op.getParent() instanceof Assignment
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
// flow from anything on the RHS of an assignment to a time/date structure to that
|
||||
// assignment.
|
||||
exists(StructLikeClass dds, FieldAccess fa, Assignment aexpr, Expr e |
|
||||
e = node1.asExpr() and
|
||||
fa = node2.asExpr()
|
||||
|
|
||||
(dds instanceof PackedTimeType or dds instanceof UnpackedTimeType) and
|
||||
fa.getQualifier().getUnderlyingType() = dds and
|
||||
aexpr.getLValue() = fa and
|
||||
aexpr.getRValue().getAChild*() = e
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(StructLikeClass dds, FieldAccess fa, AssignExpr aexpr |
|
||||
aexpr.getRValue() = sink.asExpr()
|
||||
|
|
||||
(dds instanceof PackedTimeType or dds instanceof UnpackedTimeType) and
|
||||
fa.getQualifier().getUnderlyingType() = dds and
|
||||
fa.isModified() and
|
||||
aexpr.getLValue() = fa
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Taint configuration for finding an operation with hardcoded 365 that will flow into any known date/time field.
|
||||
*/
|
||||
|
||||
@@ -129,24 +129,6 @@ class NetworkFunctionCall extends FunctionCall {
|
||||
NetworkFunctionCall() { this.getTarget().hasName(["ntohd", "ntohf", "ntohl", "ntohll", "ntohs"]) }
|
||||
}
|
||||
|
||||
deprecated class NetworkToBufferSizeConfiguration extends DataFlow::Configuration {
|
||||
NetworkToBufferSizeConfiguration() { this = "NetworkToBufferSizeConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node node) { node.asExpr() instanceof NetworkFunctionCall }
|
||||
|
||||
override predicate isSink(DataFlow::Node node) {
|
||||
node.asExpr() = any(BufferAccess ba).getAccessedLength()
|
||||
}
|
||||
|
||||
override predicate isBarrier(DataFlow::Node node) {
|
||||
exists(GuardCondition gc, GVN gvn |
|
||||
gc.getAChild*() = gvn.getAnExpr() and
|
||||
globalValueNumber(node.asExpr()) = gvn and
|
||||
gc.controls(node.asExpr().getBasicBlock(), _)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private module NetworkToBufferSizeConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node node) { node.asExpr() instanceof NetworkFunctionCall }
|
||||
|
||||
|
||||
@@ -41,20 +41,6 @@ class ExternalApiDataNode extends DataFlow::Node {
|
||||
string getFunctionDescription() { result = this.getExternalFunction().toString() }
|
||||
}
|
||||
|
||||
/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. */
|
||||
deprecated class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration {
|
||||
UntrustedDataToExternalApiConfig() { this = "UntrustedDataToExternalAPIConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists(RemoteFlowSourceFunction remoteFlow |
|
||||
remoteFlow = source.asExpr().(Call).getTarget() and
|
||||
remoteFlow.hasRemoteFlowSource(_, _)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode }
|
||||
}
|
||||
|
||||
/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. */
|
||||
private module UntrustedDataToExternalApiConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
|
||||
@@ -41,15 +41,6 @@ class ExternalApiDataNode extends DataFlow::Node {
|
||||
string getFunctionDescription() { result = this.getExternalFunction().toString() }
|
||||
}
|
||||
|
||||
/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. */
|
||||
deprecated class UntrustedDataToExternalApiConfig extends TaintTracking::Configuration {
|
||||
UntrustedDataToExternalApiConfig() { this = "UntrustedDataToExternalAPIConfigIR" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode }
|
||||
}
|
||||
|
||||
/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalApiDataNode`s. */
|
||||
private module UntrustedDataToExternalApiConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
@@ -26,6 +26,7 @@ from
|
||||
BufferAccess ba, string bufferDesc, int accessSize, int accessType, Element bufferAlloc,
|
||||
int bufferSize, string message
|
||||
where
|
||||
accessType != 4 and
|
||||
accessSize = ba.getSize() and
|
||||
bufferSize = getBufferSize(ba.getBuffer(bufferDesc, accessType), bufferAlloc) and
|
||||
(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* This file provides the `bounded` predicate that is used in both `cpp/uncontrolled-arithmetic`
|
||||
* and `cpp/tainted-arithmetic`.
|
||||
* This file provides the `bounded` predicate that is used in `cpp/uncontrolled-arithmetic`,
|
||||
* `cpp/tainted-arithmetic` and `cpp/uncontrolled-allocation-size`.
|
||||
*/
|
||||
|
||||
private import cpp
|
||||
@@ -8,20 +8,18 @@ private import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
||||
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
|
||||
|
||||
/**
|
||||
* An operand `e` of a bitwise and expression `andExpr` (i.e., `andExpr` is either an `BitwiseAndExpr`
|
||||
* or an `AssignAndExpr`) with operands `operand1` and `operand2` is the operand that is not `e` is upper
|
||||
* bounded by some number that is less than the maximum integer allowed by the result type of `andExpr`.
|
||||
* An operand `operand` of a bitwise and expression `andExpr` (i.e., `andExpr` is either a
|
||||
* `BitwiseAndExpr` or an `AssignAndExpr`) is upper bounded by some number that is less than the
|
||||
* maximum integer allowed by the result type of `andExpr`.
|
||||
*/
|
||||
pragma[inline]
|
||||
private predicate boundedBitwiseAnd(Expr e, Expr andExpr, Expr operand1, Expr operand2) {
|
||||
operand1 != operand2 and
|
||||
e = operand1 and
|
||||
upperBound(operand2.getFullyConverted()) < exprMaxVal(andExpr.getFullyConverted())
|
||||
private predicate boundedBitwiseAnd(Expr operand, Expr andExpr) {
|
||||
upperBound(operand.getFullyConverted()) < exprMaxVal(andExpr.getFullyConverted())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `e` is an arithmetic expression that cannot overflow, or if `e` is an operand of an
|
||||
* operation that may greatly reduce the range of possible values.
|
||||
* Holds if `e` is an arithmetic expression that cannot overflow, or if `e` is an operation that
|
||||
* may greatly reduce the range of possible values.
|
||||
*/
|
||||
predicate bounded(Expr e) {
|
||||
// There can be two separate reasons for `convertedExprMightOverflow` not holding:
|
||||
@@ -35,25 +33,25 @@ predicate bounded(Expr e) {
|
||||
) and
|
||||
not convertedExprMightOverflow(e)
|
||||
or
|
||||
// Optimistically assume that a remainder expression always yields a much smaller value.
|
||||
e = any(RemExpr rem).getLeftOperand()
|
||||
// Optimistically assume that the following operations always yields a much smaller value.
|
||||
e instanceof RemExpr
|
||||
or
|
||||
e = any(AssignRemExpr rem).getLValue()
|
||||
e instanceof DivExpr
|
||||
or
|
||||
e instanceof RShiftExpr
|
||||
or
|
||||
exists(BitwiseAndExpr andExpr |
|
||||
boundedBitwiseAnd(e, andExpr, andExpr.getAnOperand(), andExpr.getAnOperand())
|
||||
e = andExpr and boundedBitwiseAnd(andExpr.getAnOperand(), andExpr)
|
||||
)
|
||||
or
|
||||
exists(AssignAndExpr andExpr |
|
||||
boundedBitwiseAnd(e, andExpr, andExpr.getAnOperand(), andExpr.getAnOperand())
|
||||
)
|
||||
or
|
||||
// Optimistically assume that a division always yields a much smaller value.
|
||||
e = any(DivExpr div).getLeftOperand()
|
||||
// For the assignment variant of the operations we place the barrier on the assigned lvalue.
|
||||
e = any(AssignRemExpr rem).getLValue()
|
||||
or
|
||||
e = any(AssignDivExpr div).getLValue()
|
||||
or
|
||||
e = any(RShiftExpr shift).getLeftOperand()
|
||||
or
|
||||
e = any(AssignRShiftExpr div).getLValue()
|
||||
or
|
||||
exists(AssignAndExpr andExpr |
|
||||
e = andExpr.getLValue() and boundedBitwiseAnd(andExpr.getRValue(), andExpr)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||
import semmle.code.cpp.controlflow.Guards
|
||||
import semmle.code.cpp.models.implementations.NoexceptFunction
|
||||
|
||||
/** Gets the `Constructor` invoked when `newExpr` allocates memory. */
|
||||
Constructor getConstructorForAllocation(NewOrNewArrayExpr newExpr) {
|
||||
@@ -44,9 +45,8 @@ predicate deleteMayThrow(DeleteOrDeleteArrayExpr deleteExpr) {
|
||||
* like it might throw an exception, and the function does not have a `noexcept` or `throw()` specifier.
|
||||
*/
|
||||
predicate functionMayThrow(Function f) {
|
||||
(not exists(f.getBlock()) or stmtMayThrow(f.getBlock())) and
|
||||
not f.isNoExcept() and
|
||||
not f.isNoThrow()
|
||||
not f instanceof NonThrowingFunction and
|
||||
(not exists(f.getBlock()) or stmtMayThrow(f.getBlock()))
|
||||
}
|
||||
|
||||
/** Holds if the evaluation of `stmt` may throw an exception. */
|
||||
@@ -172,8 +172,7 @@ class ThrowingAllocator extends Function {
|
||||
not exists(Parameter p | p = this.getAParameter() |
|
||||
p.getUnspecifiedType().stripType() instanceof NoThrowType
|
||||
) and
|
||||
not this.isNoExcept() and
|
||||
not this.isNoThrow()
|
||||
not this instanceof NoexceptFunction
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
7
cpp/ql/src/change-notes/released/1.2.3.md
Normal file
7
cpp/ql/src/change-notes/released/1.2.3.md
Normal file
@@ -0,0 +1,7 @@
|
||||
## 1.2.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Removed false positives caused by buffer accesses in unreachable code
|
||||
* Removed false positives caused by inconsistent type checking
|
||||
* Add modeling of C functions that don't throw, thereby increasing the precision of the `cpp/incorrect-allocation-error-handling` ("Incorrect allocation-error handling") query. The query now produces additional true positives.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.2.2
|
||||
lastReleaseVersion: 1.2.3
|
||||
|
||||
26
cpp/ql/src/experimental/Security/CWE/CWE-409/Brotli.qll
Normal file
26
cpp/ql/src/experimental/Security/CWE/CWE-409/Brotli.qll
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* https://github.com/google/brotli
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import DecompressionBomb
|
||||
|
||||
/**
|
||||
* The `BrotliDecoderDecompress` function is used in flow sink.
|
||||
* See https://www.brotli.org/decode.html.
|
||||
*/
|
||||
class BrotliDecoderDecompressFunction extends DecompressionFunction {
|
||||
BrotliDecoderDecompressFunction() { this.hasGlobalName("BrotliDecoderDecompress") }
|
||||
|
||||
override int getArchiveParameterIndex() { result = 1 }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `BrotliDecoderDecompressStream` function is used in flow sink.
|
||||
* See https://www.brotli.org/decode.html.
|
||||
*/
|
||||
class BrotliDecoderDecompressStreamFunction extends DecompressionFunction {
|
||||
BrotliDecoderDecompressStreamFunction() { this.hasGlobalName("BrotliDecoderDecompressStream") }
|
||||
|
||||
override int getArchiveParameterIndex() { result = 2 }
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import MiniZip
|
||||
import ZlibGzopen
|
||||
import ZlibInflator
|
||||
import ZlibUncompress
|
||||
import LibArchive
|
||||
import ZSTD
|
||||
import Brotli
|
||||
|
||||
/**
|
||||
* The Decompression Sink instances, extend this class to define new decompression sinks.
|
||||
*/
|
||||
abstract class DecompressionFunction extends Function {
|
||||
abstract int getArchiveParameterIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* The Decompression Flow Steps, extend this class to define new decompression sinks.
|
||||
*/
|
||||
abstract class DecompressionFlowStep extends string {
|
||||
bindingset[this]
|
||||
DecompressionFlowStep() { any() }
|
||||
|
||||
abstract predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>Extracting Compressed files with any compression algorithm like gzip can cause denial of service attacks.</p>
|
||||
<p>Attackers can compress a huge file consisting of repeated similiar bytes into a small compressed file.</p>
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>When you want to decompress a user-provided compressed file you must be careful about the decompression ratio or read these files within a loop byte by byte to be able to manage the decompressed size in each cycle of the loop.</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
Reading an uncompressed Gzip file within a loop and check for a threshold size in each cycle.
|
||||
</p>
|
||||
<sample src="example_good.cpp"/>
|
||||
|
||||
<p>
|
||||
The following example is unsafe, as we do not check the uncompressed size.
|
||||
</p>
|
||||
<sample src="example_bad.cpp" />
|
||||
|
||||
</example>
|
||||
|
||||
<references>
|
||||
|
||||
<li>
|
||||
<a href="https://zlib.net/manual.html">Zlib documentation</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="https://www.bamsoftware.com/hacks/zipbomb/">An explanation of the attack</a>
|
||||
</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* @name User-controlled file decompression
|
||||
* @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision low
|
||||
* @id cpp/data-decompression-bomb
|
||||
* @tags security
|
||||
* experimental
|
||||
* external/cwe/cwe-409
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
import DecompressionBomb
|
||||
|
||||
predicate isSink(FunctionCall fc, DataFlow::Node sink) {
|
||||
exists(DecompressionFunction f | fc.getTarget() = f |
|
||||
fc.getArgument(f.getArchiveParameterIndex()) = [sink.asExpr(), sink.asIndirectExpr()]
|
||||
)
|
||||
}
|
||||
|
||||
module DecompressionTaintConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof FlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { isSink(_, sink) }
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
any(DecompressionFlowStep s).isAdditionalFlowStep(node1, node2)
|
||||
}
|
||||
}
|
||||
|
||||
module DecompressionTaint = TaintTracking::Global<DecompressionTaintConfig>;
|
||||
|
||||
import DecompressionTaint::PathGraph
|
||||
|
||||
from DecompressionTaint::PathNode source, DecompressionTaint::PathNode sink, FunctionCall fc
|
||||
where DecompressionTaint::flowPath(source, sink) and isSink(fc, sink.getNode())
|
||||
select sink.getNode(), source, sink, "The decompression output of $@ is not limited", fc,
|
||||
fc.getTarget().getName()
|
||||
32
cpp/ql/src/experimental/Security/CWE/CWE-409/LibArchive.qll
Normal file
32
cpp/ql/src/experimental/Security/CWE/CWE-409/LibArchive.qll
Normal file
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* https://github.com/libarchive/libarchive/wiki
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import DecompressionBomb
|
||||
|
||||
/**
|
||||
* The `archive_read_data*` functions are used in flow sink.
|
||||
* See https://github.com/libarchive/libarchive/wiki/Examples.
|
||||
*/
|
||||
class Archive_read_data_block extends DecompressionFunction {
|
||||
Archive_read_data_block() {
|
||||
this.hasGlobalName(["archive_read_data_block", "archive_read_data", "archive_read_data_into_fd"])
|
||||
}
|
||||
|
||||
override int getArchiveParameterIndex() { result = 0 }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `archive_read_open_filename` function as a flow step.
|
||||
*/
|
||||
class ReadOpenFunctionStep extends DecompressionFlowStep {
|
||||
ReadOpenFunctionStep() { this = "ReadOpenFunction" }
|
||||
|
||||
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(FunctionCall fc | fc.getTarget().hasGlobalName("archive_read_open_filename") |
|
||||
node1.asIndirectExpr() = fc.getArgument(1) and
|
||||
node2.asIndirectExpr() = fc.getArgument(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
56
cpp/ql/src/experimental/Security/CWE/CWE-409/MiniZip.qll
Normal file
56
cpp/ql/src/experimental/Security/CWE/CWE-409/MiniZip.qll
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* https://github.com/zlib-ng/minizip-ng
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import DecompressionBomb
|
||||
|
||||
/**
|
||||
* The `mz_zip_entry` function is used in flow sink.
|
||||
* See https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip.md.
|
||||
*/
|
||||
class Mz_zip_entry extends DecompressionFunction {
|
||||
Mz_zip_entry() { this.hasGlobalName("mz_zip_entry_read") }
|
||||
|
||||
override int getArchiveParameterIndex() { result = 1 }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `mz_zip_reader_entry_*` and `mz_zip_reader_save_all` functions are used in flow sink.
|
||||
* See https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip_rw.md.
|
||||
*/
|
||||
class Mz_zip_reader_entry extends DecompressionFunction {
|
||||
Mz_zip_reader_entry() {
|
||||
this.hasGlobalName([
|
||||
"mz_zip_reader_entry_save", "mz_zip_reader_entry_read", "mz_zip_reader_entry_save_process",
|
||||
"mz_zip_reader_entry_save_file", "mz_zip_reader_entry_save_buffer", "mz_zip_reader_save_all"
|
||||
])
|
||||
}
|
||||
|
||||
override int getArchiveParameterIndex() { result = 0 }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `UnzOpen*` functions are used in flow sink.
|
||||
*/
|
||||
class UnzOpenFunction extends DecompressionFunction {
|
||||
UnzOpenFunction() { this.hasGlobalName(["UnzOpen", "unzOpen64", "unzOpen2", "unzOpen2_64"]) }
|
||||
|
||||
override int getArchiveParameterIndex() { result = 0 }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `mz_zip_reader_open_file` and `mz_zip_reader_open_file_in_memory` functions as a flow step.
|
||||
*/
|
||||
class ReaderOpenFunctionStep extends DecompressionFlowStep {
|
||||
ReaderOpenFunctionStep() { this = "ReaderOpenFunctionStep" }
|
||||
|
||||
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(FunctionCall fc |
|
||||
fc.getTarget().hasGlobalName(["mz_zip_reader_open_file_in_memory", "mz_zip_reader_open_file"])
|
||||
|
|
||||
node1.asIndirectExpr() = fc.getArgument(1) and
|
||||
node2.asIndirectExpr() = fc.getArgument(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
88
cpp/ql/src/experimental/Security/CWE/CWE-409/ZSTD.qll
Normal file
88
cpp/ql/src/experimental/Security/CWE/CWE-409/ZSTD.qll
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* https://github.com/facebook/zstd/blob/dev/examples/streaming_decompression.c
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import DecompressionBomb
|
||||
|
||||
/**
|
||||
* The `ZSTD_decompress` function is used in flow sink.
|
||||
*/
|
||||
class ZstdDecompressFunction extends DecompressionFunction {
|
||||
ZstdDecompressFunction() { this.hasGlobalName("ZSTD_decompress") }
|
||||
|
||||
override int getArchiveParameterIndex() { result = 2 }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `ZSTD_decompressDCtx` function is used in flow sink.
|
||||
*/
|
||||
class ZstdDecompressDctxFunction extends DecompressionFunction {
|
||||
ZstdDecompressDctxFunction() { this.hasGlobalName("ZSTD_decompressDCtx") }
|
||||
|
||||
override int getArchiveParameterIndex() { result = 3 }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `ZSTD_decompressStream` function is used in flow sink.
|
||||
*/
|
||||
class ZstdDecompressStreamFunction extends DecompressionFunction {
|
||||
ZstdDecompressStreamFunction() { this.hasGlobalName("ZSTD_decompressStream") }
|
||||
|
||||
override int getArchiveParameterIndex() { result = 2 }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `ZSTD_decompress_usingDDict` function is used in flow sink.
|
||||
*/
|
||||
class ZstdDecompressUsingDdictFunction extends DecompressionFunction {
|
||||
ZstdDecompressUsingDdictFunction() { this.hasGlobalName("ZSTD_decompress_usingDDict") }
|
||||
|
||||
override int getArchiveParameterIndex() { result = 3 }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `fopen_orDie` function as a flow step.
|
||||
*/
|
||||
class FopenOrDieFunctionStep extends DecompressionFlowStep {
|
||||
FopenOrDieFunctionStep() { this = "FopenOrDieFunctionStep" }
|
||||
|
||||
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(FunctionCall fc | fc.getTarget().hasGlobalName("fopen_orDie") |
|
||||
node1.asIndirectExpr() = fc.getArgument(0) and
|
||||
node2.asExpr() = fc
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `fread_orDie` function as a flow step.
|
||||
*/
|
||||
class FreadOrDieFunctionStep extends DecompressionFlowStep {
|
||||
FreadOrDieFunctionStep() { this = "FreadOrDieFunctionStep" }
|
||||
|
||||
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(FunctionCall fc | fc.getTarget().hasGlobalName("fread_orDie") |
|
||||
node1.asExpr() = fc.getArgument(2) and
|
||||
node2.asIndirectExpr() = fc.getArgument(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `src` member of a `ZSTD_inBuffer` variable is used in a flow steps.
|
||||
*/
|
||||
class SrcMember extends DecompressionFlowStep {
|
||||
SrcMember() { this = "SrcMember" }
|
||||
|
||||
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(VariableAccess inBufferAccess, Field srcField, ClassAggregateLiteral c |
|
||||
inBufferAccess.getType().hasName("ZSTD_inBuffer") and
|
||||
srcField.hasName("src")
|
||||
|
|
||||
node2.asExpr() = inBufferAccess and
|
||||
inBufferAccess.getTarget().getInitializer().getExpr() = c and
|
||||
node1.asIndirectExpr() = c.getFieldExpr(srcField, _)
|
||||
)
|
||||
}
|
||||
}
|
||||
71
cpp/ql/src/experimental/Security/CWE/CWE-409/ZlibGzopen.qll
Normal file
71
cpp/ql/src/experimental/Security/CWE/CWE-409/ZlibGzopen.qll
Normal file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* https://www.zlib.net/
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import DecompressionBomb
|
||||
|
||||
/**
|
||||
* The `gzfread` function is used in flow sink.
|
||||
*
|
||||
* `gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file)`
|
||||
*/
|
||||
class GzFreadFunction extends DecompressionFunction {
|
||||
GzFreadFunction() { this.hasGlobalName("gzfread") }
|
||||
|
||||
override int getArchiveParameterIndex() { result = 3 }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `gzgets` function is used in flow sink.
|
||||
*
|
||||
* `gzgets(gzFile file, char *buf, int len)`
|
||||
*/
|
||||
class GzGetsFunction extends DecompressionFunction {
|
||||
GzGetsFunction() { this.hasGlobalName("gzgets") }
|
||||
|
||||
override int getArchiveParameterIndex() { result = 0 }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `gzread` function is used in flow sink.
|
||||
*
|
||||
* `gzread(gzFile file, voidp buf, unsigned len)`
|
||||
*/
|
||||
class GzReadFunction extends DecompressionFunction {
|
||||
GzReadFunction() { this.hasGlobalName("gzread") }
|
||||
|
||||
override int getArchiveParameterIndex() { result = 0 }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `gzdopen` function is used in flow steps.
|
||||
*
|
||||
* `gzdopen(int fd, const char *mode)`
|
||||
*/
|
||||
class GzdopenFunctionStep extends DecompressionFlowStep {
|
||||
GzdopenFunctionStep() { this = "GzdopenFunctionStep" }
|
||||
|
||||
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(FunctionCall fc | fc.getTarget().hasGlobalName("gzdopen") |
|
||||
node1.asExpr() = fc.getArgument(0) and
|
||||
node2.asExpr() = fc
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `gzopen` function is used in flow steps.
|
||||
*
|
||||
* `gzopen(const char *path, const char *mode)`
|
||||
*/
|
||||
class GzopenFunctionStep extends DecompressionFlowStep {
|
||||
GzopenFunctionStep() { this = "GzopenFunctionStep" }
|
||||
|
||||
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(FunctionCall fc | fc.getTarget().hasGlobalName("gzopen") |
|
||||
node1.asIndirectExpr() = fc.getArgument(0) and
|
||||
node2.asExpr() = fc
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* https://www.zlib.net/
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import DecompressionBomb
|
||||
|
||||
/**
|
||||
* The `inflate` and `inflateSync` functions are used in flow sink.
|
||||
*
|
||||
* `inflate(z_stream strm, int flush)`
|
||||
*
|
||||
* `inflateSync(z_stream strm)`
|
||||
*/
|
||||
class InflateFunction extends DecompressionFunction {
|
||||
InflateFunction() { this.hasGlobalName(["inflate", "inflateSync"]) }
|
||||
|
||||
override int getArchiveParameterIndex() { result = 0 }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `next_in` member of a `z_stream` variable is used in a flow steps.
|
||||
*/
|
||||
class NextInMemberStep extends DecompressionFlowStep {
|
||||
NextInMemberStep() { this = "NextInMemberStep" }
|
||||
|
||||
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(Variable nextInVar |
|
||||
nextInVar.getDeclaringType().hasName("z_stream") and
|
||||
nextInVar.hasName("next_in")
|
||||
|
|
||||
node1.asIndirectExpr() = nextInVar.getAnAssignedValue() and
|
||||
node2.asExpr() =
|
||||
nextInVar.getAnAccess().getQualifier().(VariableAccess).getTarget().getAnAccess()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* https://www.zlib.net/
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import DecompressionBomb
|
||||
|
||||
/**
|
||||
* The `uncompress`/`uncompress2` function is used in flow sink.
|
||||
*/
|
||||
class UncompressFunction extends DecompressionFunction {
|
||||
UncompressFunction() { this.hasGlobalName(["uncompress", "uncompress2"]) }
|
||||
|
||||
override int getArchiveParameterIndex() { result = 2 }
|
||||
}
|
||||
15
cpp/ql/src/experimental/Security/CWE/CWE-409/example_bad.cpp
Normal file
15
cpp/ql/src/experimental/Security/CWE/CWE-409/example_bad.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "zlib.h"
|
||||
|
||||
void UnsafeGzread(gzFile inFileZ) {
|
||||
const int BUFFER_SIZE = 8192;
|
||||
unsigned char unzipBuffer[BUFFER_SIZE];
|
||||
unsigned int unzippedBytes;
|
||||
while (true) {
|
||||
unzippedBytes = gzread(inFileZ, unzipBuffer, BUFFER_SIZE);
|
||||
if (unzippedBytes <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// process buffer
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#include "zlib.h"
|
||||
|
||||
void SafeGzread(gzFile inFileZ) {
|
||||
const int MAX_READ = 1024 * 1024 * 4;
|
||||
const int BUFFER_SIZE = 8192;
|
||||
unsigned char unzipBuffer[BUFFER_SIZE];
|
||||
unsigned int unzippedBytes;
|
||||
unsigned int totalRead = 0;
|
||||
while (true) {
|
||||
unzippedBytes = gzread(inFileZ, unzipBuffer, BUFFER_SIZE);
|
||||
totalRead += unzippedBytes;
|
||||
if (unzippedBytes <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (totalRead > MAX_READ) {
|
||||
// Possible decompression bomb, stop processing.
|
||||
break;
|
||||
} else {
|
||||
// process buffer
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 1.2.2
|
||||
version: 1.2.3
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
edges
|
||||
| brotliTest.cpp:15:41:15:44 | **argv | brotliTest.cpp:15:41:15:44 | **argv | provenance | |
|
||||
| brotliTest.cpp:15:41:15:44 | **argv | brotliTest.cpp:18:35:18:53 | *access to array | provenance | |
|
||||
| brotliTest.cpp:15:41:15:44 | **argv | brotliTest.cpp:21:30:21:52 | *access to array | provenance | |
|
||||
| brotliTest.cpp:21:30:21:52 | *access to array | brotliTest.cpp:24:51:24:58 | **& ... | provenance | |
|
||||
| libarchiveTests.cpp:16:31:16:32 | *ar | libarchiveTests.cpp:16:31:16:32 | *ar | provenance | |
|
||||
| libarchiveTests.cpp:16:31:16:32 | *ar | libarchiveTests.cpp:22:41:22:42 | *ar | provenance | |
|
||||
| libarchiveTests.cpp:30:45:30:48 | **argv | libarchiveTests.cpp:30:45:30:48 | **argv | provenance | |
|
||||
| libarchiveTests.cpp:30:45:30:48 | **argv | libarchiveTests.cpp:34:35:34:41 | *access to array | provenance | |
|
||||
| libarchiveTests.cpp:34:32:34:32 | *a | libarchiveTests.cpp:38:27:38:27 | *a | provenance | |
|
||||
| libarchiveTests.cpp:34:35:34:41 | *access to array | libarchiveTests.cpp:34:32:34:32 | *a | provenance | Config |
|
||||
| libarchiveTests.cpp:38:27:38:27 | *a | libarchiveTests.cpp:16:31:16:32 | *ar | provenance | |
|
||||
| libarchiveTests.cpp:38:27:38:27 | *a | libarchiveTests.cpp:38:27:38:27 | read_data output argument | provenance | |
|
||||
| libarchiveTests.cpp:38:27:38:27 | read_data output argument | libarchiveTests.cpp:38:27:38:27 | *a | provenance | |
|
||||
| main.cpp:7:33:7:36 | **argv | main.cpp:8:23:8:26 | **argv | provenance | |
|
||||
| main.cpp:7:33:7:36 | **argv | main.cpp:9:27:9:30 | **argv | provenance | |
|
||||
| main.cpp:7:33:7:36 | **argv | main.cpp:10:24:10:27 | **argv | provenance | |
|
||||
| main.cpp:7:33:7:36 | **argv | main.cpp:11:21:11:24 | **argv | provenance | |
|
||||
| main.cpp:7:33:7:36 | **argv | main.cpp:12:21:12:24 | **argv | provenance | |
|
||||
| main.cpp:8:23:8:26 | **argv | brotliTest.cpp:15:41:15:44 | **argv | provenance | |
|
||||
| main.cpp:8:23:8:26 | **argv | main.cpp:8:23:8:26 | brotli_test output argument | provenance | |
|
||||
| main.cpp:8:23:8:26 | brotli_test output argument | main.cpp:9:27:9:30 | **argv | provenance | |
|
||||
| main.cpp:8:23:8:26 | brotli_test output argument | main.cpp:10:24:10:27 | **argv | provenance | |
|
||||
| main.cpp:8:23:8:26 | brotli_test output argument | main.cpp:11:21:11:24 | **argv | provenance | |
|
||||
| main.cpp:8:23:8:26 | brotli_test output argument | main.cpp:12:21:12:24 | **argv | provenance | |
|
||||
| main.cpp:9:27:9:30 | **argv | libarchiveTests.cpp:30:45:30:48 | **argv | provenance | |
|
||||
| main.cpp:9:27:9:30 | **argv | main.cpp:9:27:9:30 | libarchive_test output argument | provenance | |
|
||||
| main.cpp:9:27:9:30 | libarchive_test output argument | main.cpp:10:24:10:27 | **argv | provenance | |
|
||||
| main.cpp:9:27:9:30 | libarchive_test output argument | main.cpp:11:21:11:24 | **argv | provenance | |
|
||||
| main.cpp:9:27:9:30 | libarchive_test output argument | main.cpp:12:21:12:24 | **argv | provenance | |
|
||||
| main.cpp:10:24:10:27 | **argv | main.cpp:10:24:10:27 | minizip_test output argument | provenance | |
|
||||
| main.cpp:10:24:10:27 | **argv | minizipTest.cpp:12:42:12:45 | **argv | provenance | |
|
||||
| main.cpp:10:24:10:27 | minizip_test output argument | main.cpp:11:21:11:24 | **argv | provenance | |
|
||||
| main.cpp:10:24:10:27 | minizip_test output argument | main.cpp:12:21:12:24 | **argv | provenance | |
|
||||
| main.cpp:11:21:11:24 | **argv | main.cpp:11:21:11:24 | zlib_test output argument | provenance | |
|
||||
| main.cpp:11:21:11:24 | **argv | main.cpp:11:21:11:24 | zlib_test output argument | provenance | |
|
||||
| main.cpp:11:21:11:24 | **argv | zlibTest.cpp:80:33:80:36 | **argv | provenance | |
|
||||
| main.cpp:11:21:11:24 | zlib_test output argument | main.cpp:12:21:12:24 | **argv | provenance | |
|
||||
| main.cpp:11:21:11:24 | zlib_test output argument | main.cpp:12:21:12:24 | *argv | provenance | |
|
||||
| main.cpp:12:21:12:24 | **argv | zstdTest.cpp:26:39:26:42 | **argv | provenance | |
|
||||
| main.cpp:12:21:12:24 | *argv | zstdTest.cpp:26:39:26:42 | **argv | provenance | |
|
||||
| main.cpp:12:21:12:24 | *argv | zstdTest.cpp:26:39:26:42 | *argv | provenance | |
|
||||
| minizipTest.cpp:12:42:12:45 | **argv | minizipTest.cpp:12:42:12:45 | **argv | provenance | |
|
||||
| minizipTest.cpp:12:42:12:45 | **argv | minizipTest.cpp:17:52:17:67 | *access to array | provenance | |
|
||||
| minizipTest.cpp:12:42:12:45 | **argv | minizipTest.cpp:24:41:24:47 | *access to array | provenance | |
|
||||
| minizipTest.cpp:12:42:12:45 | **argv | minizipTest.cpp:28:13:28:19 | *access to array | provenance | |
|
||||
| minizipTest.cpp:24:29:24:38 | **zip_reader | minizipTest.cpp:26:30:26:39 | **zip_reader | provenance | |
|
||||
| minizipTest.cpp:24:29:24:38 | *zip_reader | minizipTest.cpp:26:30:26:39 | *zip_reader | provenance | |
|
||||
| minizipTest.cpp:24:41:24:47 | *access to array | minizipTest.cpp:24:29:24:38 | **zip_reader | provenance | Config |
|
||||
| minizipTest.cpp:24:41:24:47 | *access to array | minizipTest.cpp:24:29:24:38 | *zip_reader | provenance | Config |
|
||||
| zlibTest.cpp:16:26:16:30 | *input | zlibTest.cpp:20:25:20:39 | *input | provenance | |
|
||||
| zlibTest.cpp:20:25:20:39 | *input | zlibTest.cpp:16:26:16:30 | *input | provenance | |
|
||||
| zlibTest.cpp:20:25:20:39 | *input | zlibTest.cpp:24:17:24:26 | & ... | provenance | Config |
|
||||
| zlibTest.cpp:20:25:20:39 | *input | zlibTest.cpp:25:13:25:22 | & ... | provenance | Config |
|
||||
| zlibTest.cpp:24:17:24:26 | & ... | zlibTest.cpp:25:13:25:22 | & ... | provenance | |
|
||||
| zlibTest.cpp:37:25:37:32 | *fileName | zlibTest.cpp:38:29:38:36 | *fileName | provenance | |
|
||||
| zlibTest.cpp:38:22:38:27 | call to gzopen | zlibTest.cpp:38:22:38:27 | call to gzopen | provenance | |
|
||||
| zlibTest.cpp:38:22:38:27 | call to gzopen | zlibTest.cpp:41:20:41:26 | inFileZ | provenance | |
|
||||
| zlibTest.cpp:38:29:38:36 | *fileName | zlibTest.cpp:37:25:37:32 | *fileName | provenance | |
|
||||
| zlibTest.cpp:38:29:38:36 | *fileName | zlibTest.cpp:38:22:38:27 | call to gzopen | provenance | Config |
|
||||
| zlibTest.cpp:47:26:47:33 | *fileName | zlibTest.cpp:48:29:48:36 | *fileName | provenance | |
|
||||
| zlibTest.cpp:48:22:48:27 | call to gzopen | zlibTest.cpp:48:22:48:27 | call to gzopen | provenance | |
|
||||
| zlibTest.cpp:48:22:48:27 | call to gzopen | zlibTest.cpp:51:38:51:44 | inFileZ | provenance | |
|
||||
| zlibTest.cpp:48:29:48:36 | *fileName | zlibTest.cpp:47:26:47:33 | *fileName | provenance | |
|
||||
| zlibTest.cpp:48:29:48:36 | *fileName | zlibTest.cpp:48:22:48:27 | call to gzopen | provenance | Config |
|
||||
| zlibTest.cpp:57:25:57:32 | *fileName | zlibTest.cpp:58:29:58:36 | *fileName | provenance | |
|
||||
| zlibTest.cpp:58:22:58:27 | call to gzopen | zlibTest.cpp:58:22:58:27 | call to gzopen | provenance | |
|
||||
| zlibTest.cpp:58:22:58:27 | call to gzopen | zlibTest.cpp:62:25:62:31 | inFileZ | provenance | |
|
||||
| zlibTest.cpp:58:29:58:36 | *fileName | zlibTest.cpp:57:25:57:32 | *fileName | provenance | |
|
||||
| zlibTest.cpp:58:29:58:36 | *fileName | zlibTest.cpp:58:22:58:27 | call to gzopen | provenance | Config |
|
||||
| zlibTest.cpp:71:26:71:30 | *input | zlibTest.cpp:71:26:71:30 | *input | provenance | |
|
||||
| zlibTest.cpp:71:26:71:30 | *input | zlibTest.cpp:77:45:77:59 | *input | provenance | |
|
||||
| zlibTest.cpp:80:33:80:36 | **argv | zlibTest.cpp:80:33:80:36 | **argv | provenance | |
|
||||
| zlibTest.cpp:80:33:80:36 | **argv | zlibTest.cpp:81:19:81:25 | *access to array | provenance | |
|
||||
| zlibTest.cpp:80:33:80:36 | **argv | zlibTest.cpp:82:18:82:24 | *access to array | provenance | |
|
||||
| zlibTest.cpp:80:33:80:36 | **argv | zlibTest.cpp:83:19:83:25 | *access to array | provenance | |
|
||||
| zlibTest.cpp:80:33:80:36 | **argv | zlibTest.cpp:84:18:84:24 | *access to array | provenance | |
|
||||
| zlibTest.cpp:80:33:80:36 | **argv | zlibTest.cpp:85:19:85:25 | *access to array | provenance | |
|
||||
| zlibTest.cpp:81:19:81:25 | *access to array | zlibTest.cpp:47:26:47:33 | *fileName | provenance | |
|
||||
| zlibTest.cpp:81:19:81:25 | *access to array | zlibTest.cpp:81:19:81:25 | UnsafeGzfread output argument | provenance | |
|
||||
| zlibTest.cpp:81:19:81:25 | UnsafeGzfread output argument | zlibTest.cpp:80:33:80:36 | **argv | provenance | |
|
||||
| zlibTest.cpp:81:19:81:25 | UnsafeGzfread output argument | zlibTest.cpp:80:33:80:36 | **argv [Return] | provenance | |
|
||||
| zlibTest.cpp:81:19:81:25 | UnsafeGzfread output argument | zlibTest.cpp:82:18:82:24 | *access to array | provenance | |
|
||||
| zlibTest.cpp:81:19:81:25 | UnsafeGzfread output argument | zlibTest.cpp:83:19:83:25 | *access to array | provenance | |
|
||||
| zlibTest.cpp:81:19:81:25 | UnsafeGzfread output argument | zlibTest.cpp:84:18:84:24 | *access to array | provenance | |
|
||||
| zlibTest.cpp:81:19:81:25 | UnsafeGzfread output argument | zlibTest.cpp:85:19:85:25 | *access to array | provenance | |
|
||||
| zlibTest.cpp:82:18:82:24 | *access to array | zlibTest.cpp:57:25:57:32 | *fileName | provenance | |
|
||||
| zlibTest.cpp:82:18:82:24 | *access to array | zlibTest.cpp:82:18:82:24 | UnsafeGzgets output argument | provenance | |
|
||||
| zlibTest.cpp:82:18:82:24 | UnsafeGzgets output argument | zlibTest.cpp:80:33:80:36 | **argv | provenance | |
|
||||
| zlibTest.cpp:82:18:82:24 | UnsafeGzgets output argument | zlibTest.cpp:80:33:80:36 | **argv [Return] | provenance | |
|
||||
| zlibTest.cpp:82:18:82:24 | UnsafeGzgets output argument | zlibTest.cpp:83:19:83:25 | *access to array | provenance | |
|
||||
| zlibTest.cpp:82:18:82:24 | UnsafeGzgets output argument | zlibTest.cpp:84:18:84:24 | *access to array | provenance | |
|
||||
| zlibTest.cpp:82:18:82:24 | UnsafeGzgets output argument | zlibTest.cpp:85:19:85:25 | *access to array | provenance | |
|
||||
| zlibTest.cpp:83:19:83:25 | *access to array | zlibTest.cpp:16:26:16:30 | *input | provenance | |
|
||||
| zlibTest.cpp:83:19:83:25 | *access to array | zlibTest.cpp:83:19:83:25 | UnsafeInflate output argument | provenance | |
|
||||
| zlibTest.cpp:83:19:83:25 | UnsafeInflate output argument | zlibTest.cpp:80:33:80:36 | **argv | provenance | |
|
||||
| zlibTest.cpp:83:19:83:25 | UnsafeInflate output argument | zlibTest.cpp:80:33:80:36 | **argv [Return] | provenance | |
|
||||
| zlibTest.cpp:83:19:83:25 | UnsafeInflate output argument | zlibTest.cpp:84:18:84:24 | *access to array | provenance | |
|
||||
| zlibTest.cpp:83:19:83:25 | UnsafeInflate output argument | zlibTest.cpp:85:19:85:25 | *access to array | provenance | |
|
||||
| zlibTest.cpp:84:18:84:24 | *access to array | zlibTest.cpp:37:25:37:32 | *fileName | provenance | |
|
||||
| zlibTest.cpp:84:18:84:24 | *access to array | zlibTest.cpp:84:18:84:24 | UnsafeGzread output argument | provenance | |
|
||||
| zlibTest.cpp:84:18:84:24 | UnsafeGzread output argument | zlibTest.cpp:80:33:80:36 | **argv | provenance | |
|
||||
| zlibTest.cpp:84:18:84:24 | UnsafeGzread output argument | zlibTest.cpp:80:33:80:36 | **argv [Return] | provenance | |
|
||||
| zlibTest.cpp:84:18:84:24 | UnsafeGzread output argument | zlibTest.cpp:85:19:85:25 | *access to array | provenance | |
|
||||
| zlibTest.cpp:85:19:85:25 | *access to array | zlibTest.cpp:71:26:71:30 | *input | provenance | |
|
||||
| zlibTest.cpp:85:19:85:25 | *access to array | zlibTest.cpp:85:19:85:25 | InflateString output argument | provenance | |
|
||||
| zlibTest.cpp:85:19:85:25 | InflateString output argument | zlibTest.cpp:80:33:80:36 | **argv | provenance | |
|
||||
| zlibTest.cpp:85:19:85:25 | InflateString output argument | zlibTest.cpp:80:33:80:36 | **argv [Return] | provenance | |
|
||||
| zstdTest.cpp:26:39:26:42 | **argv | zstdTest.cpp:27:35:27:41 | *access to array | provenance | |
|
||||
| zstdTest.cpp:26:39:26:42 | *argv | zstdTest.cpp:27:35:27:41 | *access to array | provenance | |
|
||||
| zstdTest.cpp:27:23:27:33 | call to fopen_orDie | zstdTest.cpp:27:23:27:33 | call to fopen_orDie | provenance | |
|
||||
| zstdTest.cpp:27:23:27:33 | call to fopen_orDie | zstdTest.cpp:35:52:35:54 | fin | provenance | |
|
||||
| zstdTest.cpp:27:35:27:41 | *access to array | zstdTest.cpp:27:23:27:33 | call to fopen_orDie | provenance | Config |
|
||||
| zstdTest.cpp:35:32:35:37 | **buffIn | zstdTest.cpp:36:32:36:37 | **buffIn | provenance | |
|
||||
| zstdTest.cpp:35:32:35:37 | *buffIn | zstdTest.cpp:36:32:36:37 | *buffIn | provenance | |
|
||||
| zstdTest.cpp:35:52:35:54 | fin | zstdTest.cpp:35:32:35:37 | **buffIn | provenance | Config |
|
||||
| zstdTest.cpp:35:52:35:54 | fin | zstdTest.cpp:35:32:35:37 | *buffIn | provenance | Config |
|
||||
| zstdTest.cpp:36:32:36:37 | **buffIn | zstdTest.cpp:35:32:35:37 | **buffIn | provenance | |
|
||||
| zstdTest.cpp:36:32:36:37 | **buffIn | zstdTest.cpp:39:69:39:74 | & ... | provenance | Config |
|
||||
| zstdTest.cpp:36:32:36:37 | **buffIn | zstdTest.cpp:39:69:39:74 | & ... | provenance | Config |
|
||||
| zstdTest.cpp:36:32:36:37 | *buffIn | zstdTest.cpp:35:32:35:37 | *buffIn | provenance | |
|
||||
| zstdTest.cpp:36:32:36:37 | *buffIn | zstdTest.cpp:39:69:39:74 | & ... | provenance | Config |
|
||||
| zstdTest.cpp:36:32:36:37 | *buffIn | zstdTest.cpp:39:69:39:74 | & ... | provenance | Config |
|
||||
| zstdTest.cpp:39:69:39:74 | & ... | zstdTest.cpp:39:69:39:74 | & ... | provenance | |
|
||||
| zstdTest.cpp:39:69:39:74 | & ... | zstdTest.cpp:39:69:39:74 | & ... | provenance | |
|
||||
nodes
|
||||
| brotliTest.cpp:15:41:15:44 | **argv | semmle.label | **argv |
|
||||
| brotliTest.cpp:15:41:15:44 | **argv | semmle.label | **argv |
|
||||
| brotliTest.cpp:18:35:18:53 | *access to array | semmle.label | *access to array |
|
||||
| brotliTest.cpp:21:30:21:52 | *access to array | semmle.label | *access to array |
|
||||
| brotliTest.cpp:24:51:24:58 | **& ... | semmle.label | **& ... |
|
||||
| libarchiveTests.cpp:16:31:16:32 | *ar | semmle.label | *ar |
|
||||
| libarchiveTests.cpp:16:31:16:32 | *ar | semmle.label | *ar |
|
||||
| libarchiveTests.cpp:22:41:22:42 | *ar | semmle.label | *ar |
|
||||
| libarchiveTests.cpp:30:45:30:48 | **argv | semmle.label | **argv |
|
||||
| libarchiveTests.cpp:30:45:30:48 | **argv | semmle.label | **argv |
|
||||
| libarchiveTests.cpp:34:32:34:32 | *a | semmle.label | *a |
|
||||
| libarchiveTests.cpp:34:35:34:41 | *access to array | semmle.label | *access to array |
|
||||
| libarchiveTests.cpp:38:27:38:27 | *a | semmle.label | *a |
|
||||
| libarchiveTests.cpp:38:27:38:27 | read_data output argument | semmle.label | read_data output argument |
|
||||
| main.cpp:7:33:7:36 | **argv | semmle.label | **argv |
|
||||
| main.cpp:8:23:8:26 | **argv | semmle.label | **argv |
|
||||
| main.cpp:8:23:8:26 | brotli_test output argument | semmle.label | brotli_test output argument |
|
||||
| main.cpp:9:27:9:30 | **argv | semmle.label | **argv |
|
||||
| main.cpp:9:27:9:30 | libarchive_test output argument | semmle.label | libarchive_test output argument |
|
||||
| main.cpp:10:24:10:27 | **argv | semmle.label | **argv |
|
||||
| main.cpp:10:24:10:27 | minizip_test output argument | semmle.label | minizip_test output argument |
|
||||
| main.cpp:11:21:11:24 | **argv | semmle.label | **argv |
|
||||
| main.cpp:11:21:11:24 | zlib_test output argument | semmle.label | zlib_test output argument |
|
||||
| main.cpp:11:21:11:24 | zlib_test output argument | semmle.label | zlib_test output argument |
|
||||
| main.cpp:12:21:12:24 | **argv | semmle.label | **argv |
|
||||
| main.cpp:12:21:12:24 | *argv | semmle.label | *argv |
|
||||
| minizipTest.cpp:12:42:12:45 | **argv | semmle.label | **argv |
|
||||
| minizipTest.cpp:12:42:12:45 | **argv | semmle.label | **argv |
|
||||
| minizipTest.cpp:17:52:17:67 | *access to array | semmle.label | *access to array |
|
||||
| minizipTest.cpp:24:29:24:38 | **zip_reader | semmle.label | **zip_reader |
|
||||
| minizipTest.cpp:24:29:24:38 | *zip_reader | semmle.label | *zip_reader |
|
||||
| minizipTest.cpp:24:41:24:47 | *access to array | semmle.label | *access to array |
|
||||
| minizipTest.cpp:26:30:26:39 | **zip_reader | semmle.label | **zip_reader |
|
||||
| minizipTest.cpp:26:30:26:39 | *zip_reader | semmle.label | *zip_reader |
|
||||
| minizipTest.cpp:28:13:28:19 | *access to array | semmle.label | *access to array |
|
||||
| zlibTest.cpp:16:26:16:30 | *input | semmle.label | *input |
|
||||
| zlibTest.cpp:16:26:16:30 | *input | semmle.label | *input |
|
||||
| zlibTest.cpp:20:25:20:39 | *input | semmle.label | *input |
|
||||
| zlibTest.cpp:24:17:24:26 | & ... | semmle.label | & ... |
|
||||
| zlibTest.cpp:25:13:25:22 | & ... | semmle.label | & ... |
|
||||
| zlibTest.cpp:37:25:37:32 | *fileName | semmle.label | *fileName |
|
||||
| zlibTest.cpp:37:25:37:32 | *fileName | semmle.label | *fileName |
|
||||
| zlibTest.cpp:38:22:38:27 | call to gzopen | semmle.label | call to gzopen |
|
||||
| zlibTest.cpp:38:22:38:27 | call to gzopen | semmle.label | call to gzopen |
|
||||
| zlibTest.cpp:38:29:38:36 | *fileName | semmle.label | *fileName |
|
||||
| zlibTest.cpp:41:20:41:26 | inFileZ | semmle.label | inFileZ |
|
||||
| zlibTest.cpp:47:26:47:33 | *fileName | semmle.label | *fileName |
|
||||
| zlibTest.cpp:47:26:47:33 | *fileName | semmle.label | *fileName |
|
||||
| zlibTest.cpp:48:22:48:27 | call to gzopen | semmle.label | call to gzopen |
|
||||
| zlibTest.cpp:48:22:48:27 | call to gzopen | semmle.label | call to gzopen |
|
||||
| zlibTest.cpp:48:29:48:36 | *fileName | semmle.label | *fileName |
|
||||
| zlibTest.cpp:51:38:51:44 | inFileZ | semmle.label | inFileZ |
|
||||
| zlibTest.cpp:57:25:57:32 | *fileName | semmle.label | *fileName |
|
||||
| zlibTest.cpp:57:25:57:32 | *fileName | semmle.label | *fileName |
|
||||
| zlibTest.cpp:58:22:58:27 | call to gzopen | semmle.label | call to gzopen |
|
||||
| zlibTest.cpp:58:22:58:27 | call to gzopen | semmle.label | call to gzopen |
|
||||
| zlibTest.cpp:58:29:58:36 | *fileName | semmle.label | *fileName |
|
||||
| zlibTest.cpp:62:25:62:31 | inFileZ | semmle.label | inFileZ |
|
||||
| zlibTest.cpp:71:26:71:30 | *input | semmle.label | *input |
|
||||
| zlibTest.cpp:71:26:71:30 | *input | semmle.label | *input |
|
||||
| zlibTest.cpp:77:45:77:59 | *input | semmle.label | *input |
|
||||
| zlibTest.cpp:80:33:80:36 | **argv | semmle.label | **argv |
|
||||
| zlibTest.cpp:80:33:80:36 | **argv | semmle.label | **argv |
|
||||
| zlibTest.cpp:80:33:80:36 | **argv [Return] | semmle.label | **argv [Return] |
|
||||
| zlibTest.cpp:81:19:81:25 | *access to array | semmle.label | *access to array |
|
||||
| zlibTest.cpp:81:19:81:25 | UnsafeGzfread output argument | semmle.label | UnsafeGzfread output argument |
|
||||
| zlibTest.cpp:82:18:82:24 | *access to array | semmle.label | *access to array |
|
||||
| zlibTest.cpp:82:18:82:24 | UnsafeGzgets output argument | semmle.label | UnsafeGzgets output argument |
|
||||
| zlibTest.cpp:83:19:83:25 | *access to array | semmle.label | *access to array |
|
||||
| zlibTest.cpp:83:19:83:25 | UnsafeInflate output argument | semmle.label | UnsafeInflate output argument |
|
||||
| zlibTest.cpp:84:18:84:24 | *access to array | semmle.label | *access to array |
|
||||
| zlibTest.cpp:84:18:84:24 | UnsafeGzread output argument | semmle.label | UnsafeGzread output argument |
|
||||
| zlibTest.cpp:85:19:85:25 | *access to array | semmle.label | *access to array |
|
||||
| zlibTest.cpp:85:19:85:25 | InflateString output argument | semmle.label | InflateString output argument |
|
||||
| zstdTest.cpp:26:39:26:42 | **argv | semmle.label | **argv |
|
||||
| zstdTest.cpp:26:39:26:42 | *argv | semmle.label | *argv |
|
||||
| zstdTest.cpp:27:23:27:33 | call to fopen_orDie | semmle.label | call to fopen_orDie |
|
||||
| zstdTest.cpp:27:23:27:33 | call to fopen_orDie | semmle.label | call to fopen_orDie |
|
||||
| zstdTest.cpp:27:35:27:41 | *access to array | semmle.label | *access to array |
|
||||
| zstdTest.cpp:35:32:35:37 | **buffIn | semmle.label | **buffIn |
|
||||
| zstdTest.cpp:35:32:35:37 | *buffIn | semmle.label | *buffIn |
|
||||
| zstdTest.cpp:35:52:35:54 | fin | semmle.label | fin |
|
||||
| zstdTest.cpp:36:32:36:37 | **buffIn | semmle.label | **buffIn |
|
||||
| zstdTest.cpp:36:32:36:37 | *buffIn | semmle.label | *buffIn |
|
||||
| zstdTest.cpp:39:69:39:74 | & ... | semmle.label | & ... |
|
||||
| zstdTest.cpp:39:69:39:74 | & ... | semmle.label | & ... |
|
||||
subpaths
|
||||
| libarchiveTests.cpp:38:27:38:27 | *a | libarchiveTests.cpp:16:31:16:32 | *ar | libarchiveTests.cpp:16:31:16:32 | *ar | libarchiveTests.cpp:38:27:38:27 | read_data output argument |
|
||||
| main.cpp:8:23:8:26 | **argv | brotliTest.cpp:15:41:15:44 | **argv | brotliTest.cpp:15:41:15:44 | **argv | main.cpp:8:23:8:26 | brotli_test output argument |
|
||||
| main.cpp:9:27:9:30 | **argv | libarchiveTests.cpp:30:45:30:48 | **argv | libarchiveTests.cpp:30:45:30:48 | **argv | main.cpp:9:27:9:30 | libarchive_test output argument |
|
||||
| main.cpp:10:24:10:27 | **argv | minizipTest.cpp:12:42:12:45 | **argv | minizipTest.cpp:12:42:12:45 | **argv | main.cpp:10:24:10:27 | minizip_test output argument |
|
||||
| main.cpp:11:21:11:24 | **argv | zlibTest.cpp:80:33:80:36 | **argv | zlibTest.cpp:80:33:80:36 | **argv | main.cpp:11:21:11:24 | zlib_test output argument |
|
||||
| main.cpp:11:21:11:24 | **argv | zlibTest.cpp:80:33:80:36 | **argv | zlibTest.cpp:80:33:80:36 | **argv [Return] | main.cpp:11:21:11:24 | zlib_test output argument |
|
||||
| main.cpp:11:21:11:24 | **argv | zlibTest.cpp:80:33:80:36 | **argv | zlibTest.cpp:80:33:80:36 | **argv [Return] | main.cpp:11:21:11:24 | zlib_test output argument |
|
||||
| zlibTest.cpp:81:19:81:25 | *access to array | zlibTest.cpp:47:26:47:33 | *fileName | zlibTest.cpp:47:26:47:33 | *fileName | zlibTest.cpp:81:19:81:25 | UnsafeGzfread output argument |
|
||||
| zlibTest.cpp:82:18:82:24 | *access to array | zlibTest.cpp:57:25:57:32 | *fileName | zlibTest.cpp:57:25:57:32 | *fileName | zlibTest.cpp:82:18:82:24 | UnsafeGzgets output argument |
|
||||
| zlibTest.cpp:83:19:83:25 | *access to array | zlibTest.cpp:16:26:16:30 | *input | zlibTest.cpp:16:26:16:30 | *input | zlibTest.cpp:83:19:83:25 | UnsafeInflate output argument |
|
||||
| zlibTest.cpp:84:18:84:24 | *access to array | zlibTest.cpp:37:25:37:32 | *fileName | zlibTest.cpp:37:25:37:32 | *fileName | zlibTest.cpp:84:18:84:24 | UnsafeGzread output argument |
|
||||
| zlibTest.cpp:85:19:85:25 | *access to array | zlibTest.cpp:71:26:71:30 | *input | zlibTest.cpp:71:26:71:30 | *input | zlibTest.cpp:85:19:85:25 | InflateString output argument |
|
||||
#select
|
||||
| brotliTest.cpp:18:35:18:53 | *access to array | main.cpp:7:33:7:36 | **argv | brotliTest.cpp:18:35:18:53 | *access to array | The decompression output of $@ is not limited | brotliTest.cpp:18:5:18:27 | call to BrotliDecoderDecompress | BrotliDecoderDecompress |
|
||||
| brotliTest.cpp:24:51:24:58 | **& ... | main.cpp:7:33:7:36 | **argv | brotliTest.cpp:24:51:24:58 | **& ... | The decompression output of $@ is not limited | brotliTest.cpp:24:5:24:33 | call to BrotliDecoderDecompressStream | BrotliDecoderDecompressStream |
|
||||
| libarchiveTests.cpp:22:41:22:42 | *ar | main.cpp:7:33:7:36 | **argv | libarchiveTests.cpp:22:41:22:42 | *ar | The decompression output of $@ is not limited | libarchiveTests.cpp:22:17:22:39 | call to archive_read_data_block | archive_read_data_block |
|
||||
| minizipTest.cpp:17:52:17:67 | *access to array | main.cpp:7:33:7:36 | **argv | minizipTest.cpp:17:52:17:67 | *access to array | The decompression output of $@ is not limited | minizipTest.cpp:17:22:17:38 | call to mz_zip_entry_read | mz_zip_entry_read |
|
||||
| minizipTest.cpp:26:30:26:39 | **zip_reader | main.cpp:7:33:7:36 | **argv | minizipTest.cpp:26:30:26:39 | **zip_reader | The decompression output of $@ is not limited | minizipTest.cpp:26:5:26:28 | call to mz_zip_reader_entry_save | mz_zip_reader_entry_save |
|
||||
| minizipTest.cpp:26:30:26:39 | *zip_reader | main.cpp:7:33:7:36 | **argv | minizipTest.cpp:26:30:26:39 | *zip_reader | The decompression output of $@ is not limited | minizipTest.cpp:26:5:26:28 | call to mz_zip_reader_entry_save | mz_zip_reader_entry_save |
|
||||
| minizipTest.cpp:28:13:28:19 | *access to array | main.cpp:7:33:7:36 | **argv | minizipTest.cpp:28:13:28:19 | *access to array | The decompression output of $@ is not limited | minizipTest.cpp:28:5:28:11 | call to UnzOpen | UnzOpen |
|
||||
| zlibTest.cpp:25:13:25:22 | & ... | main.cpp:7:33:7:36 | **argv | zlibTest.cpp:25:13:25:22 | & ... | The decompression output of $@ is not limited | zlibTest.cpp:25:5:25:11 | call to inflate | inflate |
|
||||
| zlibTest.cpp:41:20:41:26 | inFileZ | main.cpp:7:33:7:36 | **argv | zlibTest.cpp:41:20:41:26 | inFileZ | The decompression output of $@ is not limited | zlibTest.cpp:41:13:41:18 | call to gzread | gzread |
|
||||
| zlibTest.cpp:51:38:51:44 | inFileZ | main.cpp:7:33:7:36 | **argv | zlibTest.cpp:51:38:51:44 | inFileZ | The decompression output of $@ is not limited | zlibTest.cpp:51:14:51:20 | call to gzfread | gzfread |
|
||||
| zlibTest.cpp:62:25:62:31 | inFileZ | main.cpp:7:33:7:36 | **argv | zlibTest.cpp:62:25:62:31 | inFileZ | The decompression output of $@ is not limited | zlibTest.cpp:62:18:62:23 | call to gzgets | gzgets |
|
||||
| zlibTest.cpp:77:45:77:59 | *input | main.cpp:7:33:7:36 | **argv | zlibTest.cpp:77:45:77:59 | *input | The decompression output of $@ is not limited | zlibTest.cpp:77:5:77:14 | call to uncompress | uncompress |
|
||||
| zstdTest.cpp:39:69:39:74 | & ... | main.cpp:7:33:7:36 | **argv | zstdTest.cpp:39:69:39:74 | & ... | The decompression output of $@ is not limited | zstdTest.cpp:39:32:39:52 | call to ZSTD_decompressStream | ZSTD_decompressStream |
|
||||
@@ -0,0 +1 @@
|
||||
experimental/Security/CWE/CWE-409/DecompressionBombs.ql
|
||||
@@ -0,0 +1,26 @@
|
||||
typedef long unsigned int size_t;
|
||||
typedef unsigned char uint8_t;
|
||||
|
||||
enum BrotliDecoderResult {};
|
||||
struct BrotliDecoderState;
|
||||
|
||||
BrotliDecoderResult BrotliDecoderDecompress(
|
||||
size_t encoded_size, const uint8_t encoded_buffer[],
|
||||
size_t *decoded_size, uint8_t decoded_buffer[]);
|
||||
|
||||
BrotliDecoderResult BrotliDecoderDecompressStream(
|
||||
BrotliDecoderState *state, size_t *available_in, const uint8_t **next_in,
|
||||
size_t *available_out, uint8_t **next_out, size_t *total_out);
|
||||
|
||||
void brotli_test(int argc, const char **argv) {
|
||||
uint8_t output[1024];
|
||||
size_t output_size = sizeof(output);
|
||||
BrotliDecoderDecompress(1024, (uint8_t *) argv[2], &output_size, output); // BAD
|
||||
|
||||
size_t input_size = 1024;
|
||||
const uint8_t *input_p = (const uint8_t*)argv[2];
|
||||
uint8_t *output_p = output;
|
||||
size_t out_size;
|
||||
BrotliDecoderDecompressStream(0, &input_size, &input_p, &output_size, // BAD
|
||||
&output_p, &out_size);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#define ARCHIVE_EOF 1
|
||||
#define ARCHIVE_OK 0
|
||||
#define ARCHIVE_WARN (-20)
|
||||
|
||||
struct archive;
|
||||
struct archive_entry;
|
||||
typedef int size_t;
|
||||
typedef int la_int64_t;
|
||||
|
||||
archive *archive_read_new();
|
||||
int archive_read_open_filename(archive *pArchive, const char *filename, int i);
|
||||
int archive_read_next_header(archive *a, archive_entry **entry);
|
||||
int archive_entry_size(archive_entry *pEntry);
|
||||
int archive_read_data_block(archive *pArchive, const void **pVoid, size_t *pInt, la_int64_t *pInt1);
|
||||
|
||||
static int read_data(archive *ar) {
|
||||
for (;;) {
|
||||
const void *buff;
|
||||
size_t size;
|
||||
la_int64_t offset;
|
||||
|
||||
int r = archive_read_data_block(ar, &buff, &size, &offset); // BAD
|
||||
if (r == ARCHIVE_EOF)
|
||||
return ARCHIVE_OK;
|
||||
if (r < ARCHIVE_OK)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
void libarchive_test(int argc, const char **argv) {
|
||||
archive *a = archive_read_new();
|
||||
archive_entry *entry;
|
||||
|
||||
archive_read_open_filename(a, argv[1], 10240);
|
||||
for (;;) {
|
||||
archive_read_next_header(a, &entry);
|
||||
if (archive_entry_size(entry) > 0) {
|
||||
if (read_data(a) < ARCHIVE_WARN)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
void brotli_test(int argc, const char **argv);
|
||||
void libarchive_test(int argc, const char **argv);
|
||||
void minizip_test(int argc, const char **argv);
|
||||
void zlib_test(int argc, const char **argv);
|
||||
void zstd_test(int argc, const char **argv);
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
brotli_test(argc, argv);
|
||||
libarchive_test(argc, argv);
|
||||
minizip_test(argc, argv);
|
||||
zlib_test(argc, argv);
|
||||
zstd_test(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
typedef signed int int32_t;
|
||||
|
||||
void *mz_zip_reader_create();
|
||||
int32_t mz_zip_reader_open_file(void *handle, const char *path);
|
||||
int32_t mz_zip_reader_goto_first_entry(void *pVoid);
|
||||
int32_t mz_zip_reader_entry_save(void *pVoid, int stream, int write);
|
||||
int32_t mz_zip_entry_read(void *pVoid, void *buf, int32_t i);
|
||||
void UnzOpen(const char *string);
|
||||
|
||||
void *mz_zip_create();
|
||||
|
||||
void minizip_test(int argc, const char **argv) {
|
||||
void *zip_handle = mz_zip_create();
|
||||
int32_t bytes_read;
|
||||
char buf[4096];
|
||||
while(true) {
|
||||
bytes_read = mz_zip_entry_read(zip_handle, (char *) argv[1], sizeof(buf)); // BAD
|
||||
if (bytes_read <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void *zip_reader = mz_zip_reader_create();
|
||||
mz_zip_reader_open_file(zip_reader, argv[1]);
|
||||
mz_zip_reader_goto_first_entry(zip_reader);
|
||||
mz_zip_reader_entry_save(zip_reader, 0, 0); // BAD
|
||||
|
||||
UnzOpen(argv[3]); // BAD
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
typedef unsigned char Bytef;
|
||||
typedef unsigned long uLong;
|
||||
typedef uLong uLongf;
|
||||
typedef unsigned int uInt;
|
||||
|
||||
struct z_stream {
|
||||
Bytef *next_in;
|
||||
Bytef *next_out;
|
||||
uInt avail_out;
|
||||
};
|
||||
|
||||
void inflateInit(z_stream *infstream);
|
||||
void inflate(z_stream *infstream, int i);
|
||||
void inflateEnd(z_stream *infstream);
|
||||
|
||||
void UnsafeInflate(char *input) {
|
||||
unsigned char output[1024];
|
||||
|
||||
z_stream infstream;
|
||||
infstream.next_in = (Bytef *) input; // input char array
|
||||
infstream.avail_out = sizeof(output); // size of output
|
||||
infstream.next_out = output; // output char array
|
||||
|
||||
inflateInit(&infstream);
|
||||
inflate(&infstream, 0); // BAD
|
||||
}
|
||||
|
||||
|
||||
struct gzFile {
|
||||
};
|
||||
|
||||
gzFile gzopen(char *str, const char *rb);
|
||||
unsigned int gzread(gzFile gz_file, unsigned char *str, int i);
|
||||
bool gzfread(char *str, int i, int i1, gzFile gz_file);
|
||||
char *gzgets(gzFile gz_file, char *buffer, int i);
|
||||
|
||||
void UnsafeGzread(char *fileName) {
|
||||
gzFile inFileZ = gzopen(fileName, "rb");
|
||||
unsigned char unzipBuffer[8192];
|
||||
while (true) {
|
||||
if (gzread(inFileZ, unzipBuffer, 8192) <= 0) { // BAD
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UnsafeGzfread(char *fileName) {
|
||||
gzFile inFileZ = gzopen(fileName, "rb");
|
||||
while (true) {
|
||||
char buffer[1000];
|
||||
if (!gzfread(buffer, 999, 1, inFileZ)) { // BAD
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UnsafeGzgets(char *fileName) {
|
||||
gzFile inFileZ = gzopen(fileName, "rb");
|
||||
char *buffer = new char[4000000000];
|
||||
char *result;
|
||||
while (true) {
|
||||
result = gzgets(inFileZ, buffer, 1000000000); // BAD
|
||||
if (result == nullptr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);
|
||||
|
||||
void InflateString(char *input) {
|
||||
unsigned char output[1024];
|
||||
|
||||
uLong source_length = 500;
|
||||
uLong destination_length = sizeof(output);
|
||||
|
||||
uncompress(output, &destination_length, (Bytef *) input, source_length); // BAD
|
||||
}
|
||||
|
||||
void zlib_test(int argc, char **argv) {
|
||||
UnsafeGzfread(argv[2]);
|
||||
UnsafeGzgets(argv[2]);
|
||||
UnsafeInflate(argv[2]);
|
||||
UnsafeGzread(argv[2]);
|
||||
InflateString(argv[2]);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
typedef long unsigned int size_t;
|
||||
struct FILE;
|
||||
|
||||
FILE *fopen_orDie(const char *filename, const char *instruction);
|
||||
size_t fread_orDie(void *const pVoid, const size_t read, FILE *const pFile);
|
||||
void *const malloc_orDie(const size_t size);
|
||||
|
||||
struct ZSTD_DCtx;
|
||||
typedef struct ZSTD_inBuffer_s {
|
||||
const void *src;
|
||||
size_t size;
|
||||
size_t pos;
|
||||
} ZSTD_inBuffer;
|
||||
typedef struct ZSTD_outBuffer_s {
|
||||
void *dst;
|
||||
size_t size;
|
||||
size_t pos;
|
||||
} ZSTD_outBuffer;
|
||||
|
||||
const size_t ZSTD_DStreamInSize();
|
||||
const size_t ZSTD_DStreamOutSize();
|
||||
ZSTD_DCtx *const ZSTD_createDCtx();
|
||||
const size_t ZSTD_decompressStream(ZSTD_DCtx *const pCtx, ZSTD_outBuffer *pS, ZSTD_inBuffer *pS1);
|
||||
void CHECK_ZSTD(const size_t ret);
|
||||
|
||||
void zstd_test(int argc, const char **argv) {
|
||||
FILE *const fin = fopen_orDie(argv[1], "rb");
|
||||
size_t const buffInSize = ZSTD_DStreamInSize();
|
||||
void *const buffIn = malloc_orDie(buffInSize);
|
||||
size_t const buffOutSize = ZSTD_DStreamOutSize();
|
||||
void *const buffOut = malloc_orDie(buffOutSize);
|
||||
|
||||
ZSTD_DCtx *const dctx = ZSTD_createDCtx();
|
||||
size_t read;
|
||||
while ((read = fread_orDie(buffIn, buffInSize, fin))) {
|
||||
ZSTD_inBuffer input = {buffIn, read, 0};
|
||||
while (input.pos < input.size) {
|
||||
ZSTD_outBuffer output = {buffOut, buffOutSize, 0};
|
||||
size_t const ret = ZSTD_decompressStream(dctx, &output, &input); // BAD
|
||||
CHECK_ZSTD(ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,5 @@
|
||||
| main1.cpp:7:1:7:26 | #include "defines_issue.h" | Include | defines_issue.h | 1 |
|
||||
| main2.cpp:3:1:3:19 | #include "common.h" | Include | common.h | 1 |
|
||||
| main2.cpp:7:1:7:26 | #include "defines_issue.h" | Include | defines_issue.h | 1 |
|
||||
| nameclash.h:3:1:3:27 | #include_next "nameclash.h" | IncludeNext | nameclash.h | 1 |
|
||||
| nameclash.h:3:1:3:27 | #include_next "nameclash.h" | IncludeNext | subdir1/nameclash.h | 1 |
|
||||
| nameclash.h:3:1:3:27 | #include_next "nameclash.h" | IncludeNext | subdir2/nameclash.h | 1 |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// semmle-extractor-options: --clang --clang_version 180000
|
||||
// semmle-extractor-options: --clang --edg --clang_version --edg 190000
|
||||
|
||||
struct S {
|
||||
void f() {}
|
||||
@@ -108,3 +108,16 @@ bool b_is_unbounded_array2 = __is_unbounded_array(int[42]);
|
||||
|
||||
bool b_is_referenceable1 = __is_referenceable(int);
|
||||
bool b_is_referenceable2 = __is_referenceable(void);
|
||||
|
||||
bool b_is_trivially_equality_comparable1 = __is_trivially_equality_comparable(int);
|
||||
bool b_is_trivially_equality_comparable2 = __is_trivially_equality_comparable(void);
|
||||
|
||||
enum class E {
|
||||
a, b
|
||||
};
|
||||
|
||||
bool b_is_scoped_enum1 = __is_scoped_enum(E);
|
||||
bool b_is_scoped_enum2 = __is_scoped_enum(int);
|
||||
|
||||
bool b_is_trivially_relocatable1 = __is_trivially_relocatable(int);
|
||||
bool b_is_trivially_relocatable2 = __is_trivially_relocatable(void);
|
||||
|
||||
@@ -153,7 +153,21 @@
|
||||
| clang.cpp:109:28:109:50 | int | | <none> |
|
||||
| clang.cpp:110:28:110:51 | __is_referenceable | void | 0 |
|
||||
| clang.cpp:110:28:110:51 | void | | <none> |
|
||||
| clang.cpp:112:44:112:82 | __is_trivially_equality_comparable | int | 1 |
|
||||
| clang.cpp:112:44:112:82 | int | | <none> |
|
||||
| clang.cpp:113:44:113:83 | __is_trivially_equality_comparable | void | 0 |
|
||||
| clang.cpp:113:44:113:83 | void | | <none> |
|
||||
| clang.cpp:119:26:119:44 | E | | <none> |
|
||||
| clang.cpp:119:26:119:44 | __is_scoped_enum | E | 1 |
|
||||
| clang.cpp:120:26:120:46 | __is_scoped_enum | int | 0 |
|
||||
| clang.cpp:120:26:120:46 | int | | <none> |
|
||||
| clang.cpp:122:36:122:66 | __is_trivially_relocatable | int | 1 |
|
||||
| clang.cpp:122:36:122:66 | int | | <none> |
|
||||
| clang.cpp:123:36:123:67 | __is_trivially_relocatable | void | 0 |
|
||||
| clang.cpp:123:36:123:67 | void | | <none> |
|
||||
| file://:0:0:0:0 | 0 | | 0 |
|
||||
| file://:0:0:0:0 | 0 | | 0 |
|
||||
| file://:0:0:0:0 | 1 | | 1 |
|
||||
| file://:0:0:0:0 | 1 | | 1 |
|
||||
| file://:0:0:0:0 | 2 | | 2 |
|
||||
| gcc.cpp:3:25:3:25 | 8 | | 8 |
|
||||
|
||||
458
cpp/ql/test/library-tests/c11_generic/PrintAST.expected
Normal file
458
cpp/ql/test/library-tests/c11_generic/PrintAST.expected
Normal file
@@ -0,0 +1,458 @@
|
||||
#-----| [CopyAssignmentOperator] __va_list_tag& __va_list_tag::operator=(__va_list_tag const&)
|
||||
#-----| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const __va_list_tag &
|
||||
#-----| [MoveAssignmentOperator] __va_list_tag& __va_list_tag::operator=(__va_list_tag&&)
|
||||
#-----| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] __va_list_tag &&
|
||||
generic.c:
|
||||
# 3| [FormattingFunction,TopLevelFunction] int printf(char const*)
|
||||
# 3| <params>:
|
||||
# 3| getParameter(0): [Parameter] format
|
||||
# 3| Type = [PointerType] const char *
|
||||
# 14| [TopLevelFunction] int main()
|
||||
# 14| <params>:
|
||||
# 15| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 16| getStmt(0): [DeclStmt] declaration
|
||||
# 16| getDeclarationEntry(0): [VariableDeclarationEntry] definition of i
|
||||
# 16| Type = [IntType] int
|
||||
# 17| getStmt(1): [DeclStmt] declaration
|
||||
# 17| getDeclarationEntry(0): [VariableDeclarationEntry] definition of m
|
||||
# 17| Type = [CTypedefType] MYINT
|
||||
# 18| getStmt(2): [DeclStmt] declaration
|
||||
# 18| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s
|
||||
# 18| Type = [PointerType] const char *
|
||||
# 19| getStmt(3): [DeclStmt] declaration
|
||||
# 19| getDeclarationEntry(0): [VariableDeclarationEntry] definition of f
|
||||
# 19| Type = [PointerType] float ***
|
||||
# 21| getStmt(4): [ExprStmt] ExprStmt
|
||||
# 21| getExpr(): [FormattingFunctionCall,FunctionCall] call to printf
|
||||
# 21| Type = [IntType] int
|
||||
# 21| ValueCategory = prvalue
|
||||
# 21| getArgument(0): i is %s\n
|
||||
# 21| Type = [ArrayType] char[9]
|
||||
# 21| Value = [StringLiteral] "i is %s\n"
|
||||
# 21| ValueCategory = lvalue
|
||||
# 21| getArgument(1): int
|
||||
# 21| Type = [ArrayType] char[4]
|
||||
# 21| Value = [StringLiteral] "int"
|
||||
# 21| ValueCategory = lvalue
|
||||
# 21| getArgument(0).getFullyConverted(): [CStyleCast] (const char *)...
|
||||
# 21| Conversion = [PointerConversion] pointer conversion
|
||||
# 21| Type = [PointerType] const char *
|
||||
# 21| ValueCategory = prvalue
|
||||
# 21| getExpr(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 21| Type = [CharPointerType] char *
|
||||
# 21| ValueCategory = prvalue
|
||||
# 21| getArgument(1).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 21| Type = [CharPointerType] char *
|
||||
# 21| ValueCategory = prvalue
|
||||
# 21| getExpr(): [C11GenericExpr] _Generic
|
||||
# 21| Type = [ArrayType] char[4]
|
||||
# 21| Value = [C11GenericExpr] int
|
||||
# 21| ValueCategory = lvalue
|
||||
# 21| getControllingExpr(): [VariableAccess] i
|
||||
# 21| Type = [IntType] int
|
||||
# 21| ValueCategory = prvalue(load)
|
||||
# 21| getAssociationType(0): [TypeName] int
|
||||
# 21| Type = [IntType] int
|
||||
# 21| ValueCategory = prvalue
|
||||
# 21| getAssociationExpr(0): [ReuseExpr] reuse of int
|
||||
# 21| Type = [ArrayType] char[4]
|
||||
# 21| ValueCategory = lvalue
|
||||
# 21| getAssociationType(1): [TypeName] const char *
|
||||
# 21| Type = [PointerType] const char *
|
||||
# 21| ValueCategory = prvalue
|
||||
# 21| getAssociationExpr(1): string
|
||||
# 21| Type = [ArrayType] char[7]
|
||||
# 21| Value = [StringLiteral] "string"
|
||||
# 21| ValueCategory = lvalue
|
||||
# 21| getAssociationType(2): [TypeName] void
|
||||
# 21| Type = [VoidType] void
|
||||
# 21| ValueCategory = prvalue
|
||||
# 21| getAssociationExpr(2): unknown
|
||||
# 21| Type = [ArrayType] char[8]
|
||||
# 21| Value = [StringLiteral] "unknown"
|
||||
# 21| ValueCategory = lvalue
|
||||
# 21| getControllingExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 21| Type = [IntType] int
|
||||
# 21| ValueCategory = prvalue(load)
|
||||
# 22| getStmt(5): [ExprStmt] ExprStmt
|
||||
# 22| getExpr(): [FormattingFunctionCall,FunctionCall] call to printf
|
||||
# 22| Type = [IntType] int
|
||||
# 22| ValueCategory = prvalue
|
||||
# 22| getArgument(0): c is %s\n
|
||||
# 22| Type = [ArrayType] char[9]
|
||||
# 22| Value = [StringLiteral] "c is %s\n"
|
||||
# 22| ValueCategory = lvalue
|
||||
# 22| getArgument(1): int
|
||||
# 22| Type = [ArrayType] char[4]
|
||||
# 22| Value = [StringLiteral] "int"
|
||||
# 22| ValueCategory = lvalue
|
||||
# 22| getArgument(0).getFullyConverted(): [CStyleCast] (const char *)...
|
||||
# 22| Conversion = [PointerConversion] pointer conversion
|
||||
# 22| Type = [PointerType] const char *
|
||||
# 22| ValueCategory = prvalue
|
||||
# 22| getExpr(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 22| Type = [CharPointerType] char *
|
||||
# 22| ValueCategory = prvalue
|
||||
# 22| getArgument(1).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 22| Type = [CharPointerType] char *
|
||||
# 22| ValueCategory = prvalue
|
||||
# 22| getExpr(): [C11GenericExpr] _Generic
|
||||
# 22| Type = [ArrayType] char[4]
|
||||
# 22| Value = [C11GenericExpr] int
|
||||
# 22| ValueCategory = lvalue
|
||||
# 22| getControllingExpr(): [VariableAccess] m
|
||||
# 22| Type = [CTypedefType] MYINT
|
||||
# 22| ValueCategory = prvalue(load)
|
||||
# 22| getAssociationType(0): [TypeName] int
|
||||
# 22| Type = [IntType] int
|
||||
# 22| ValueCategory = prvalue
|
||||
# 22| getAssociationExpr(0): [ReuseExpr] reuse of int
|
||||
# 22| Type = [ArrayType] char[4]
|
||||
# 22| ValueCategory = lvalue
|
||||
# 22| getAssociationType(1): [TypeName] const char *
|
||||
# 22| Type = [PointerType] const char *
|
||||
# 22| ValueCategory = prvalue
|
||||
# 22| getAssociationExpr(1): string
|
||||
# 22| Type = [ArrayType] char[7]
|
||||
# 22| Value = [StringLiteral] "string"
|
||||
# 22| ValueCategory = lvalue
|
||||
# 22| getAssociationType(2): [TypeName] void
|
||||
# 22| Type = [VoidType] void
|
||||
# 22| ValueCategory = prvalue
|
||||
# 22| getAssociationExpr(2): unknown
|
||||
# 22| Type = [ArrayType] char[8]
|
||||
# 22| Value = [StringLiteral] "unknown"
|
||||
# 22| ValueCategory = lvalue
|
||||
# 22| getControllingExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 22| Type = [CTypedefType] MYINT
|
||||
# 22| ValueCategory = prvalue(load)
|
||||
# 23| getStmt(6): [ExprStmt] ExprStmt
|
||||
# 23| getExpr(): [FormattingFunctionCall,FunctionCall] call to printf
|
||||
# 23| Type = [IntType] int
|
||||
# 23| ValueCategory = prvalue
|
||||
# 23| getArgument(0): s is %s\n
|
||||
# 23| Type = [ArrayType] char[9]
|
||||
# 23| Value = [StringLiteral] "s is %s\n"
|
||||
# 23| ValueCategory = lvalue
|
||||
# 23| getArgument(1): string
|
||||
# 23| Type = [ArrayType] char[7]
|
||||
# 23| Value = [StringLiteral] "string"
|
||||
# 23| ValueCategory = lvalue
|
||||
# 23| getArgument(0).getFullyConverted(): [CStyleCast] (const char *)...
|
||||
# 23| Conversion = [PointerConversion] pointer conversion
|
||||
# 23| Type = [PointerType] const char *
|
||||
# 23| ValueCategory = prvalue
|
||||
# 23| getExpr(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 23| Type = [CharPointerType] char *
|
||||
# 23| ValueCategory = prvalue
|
||||
# 23| getArgument(1).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 23| Type = [CharPointerType] char *
|
||||
# 23| ValueCategory = prvalue
|
||||
# 23| getExpr(): [C11GenericExpr] _Generic
|
||||
# 23| Type = [ArrayType] char[7]
|
||||
# 23| Value = [C11GenericExpr] string
|
||||
# 23| ValueCategory = lvalue
|
||||
# 23| getControllingExpr(): [VariableAccess] s
|
||||
# 23| Type = [PointerType] const char *
|
||||
# 23| ValueCategory = prvalue(load)
|
||||
# 23| getAssociationType(0): [TypeName] int
|
||||
# 23| Type = [IntType] int
|
||||
# 23| ValueCategory = prvalue
|
||||
# 23| getAssociationExpr(0): int
|
||||
# 23| Type = [ArrayType] char[4]
|
||||
# 23| Value = [StringLiteral] "int"
|
||||
# 23| ValueCategory = lvalue
|
||||
# 23| getAssociationType(1): [TypeName] const char *
|
||||
# 23| Type = [PointerType] const char *
|
||||
# 23| ValueCategory = prvalue
|
||||
# 23| getAssociationExpr(1): [ReuseExpr] reuse of string
|
||||
# 23| Type = [ArrayType] char[7]
|
||||
# 23| ValueCategory = lvalue
|
||||
# 23| getAssociationType(2): [TypeName] void
|
||||
# 23| Type = [VoidType] void
|
||||
# 23| ValueCategory = prvalue
|
||||
# 23| getAssociationExpr(2): unknown
|
||||
# 23| Type = [ArrayType] char[8]
|
||||
# 23| Value = [StringLiteral] "unknown"
|
||||
# 23| ValueCategory = lvalue
|
||||
# 23| getControllingExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 23| Type = [PointerType] const char *
|
||||
# 23| ValueCategory = prvalue(load)
|
||||
# 24| getStmt(7): [ExprStmt] ExprStmt
|
||||
# 24| getExpr(): [FormattingFunctionCall,FunctionCall] call to printf
|
||||
# 24| Type = [IntType] int
|
||||
# 24| ValueCategory = prvalue
|
||||
# 24| getArgument(0): f is %s\n
|
||||
# 24| Type = [ArrayType] char[9]
|
||||
# 24| Value = [StringLiteral] "f is %s\n"
|
||||
# 24| ValueCategory = lvalue
|
||||
# 24| getArgument(1): unknown
|
||||
# 24| Type = [ArrayType] char[8]
|
||||
# 24| Value = [StringLiteral] "unknown"
|
||||
# 24| ValueCategory = lvalue
|
||||
# 24| getArgument(0).getFullyConverted(): [CStyleCast] (const char *)...
|
||||
# 24| Conversion = [PointerConversion] pointer conversion
|
||||
# 24| Type = [PointerType] const char *
|
||||
# 24| ValueCategory = prvalue
|
||||
# 24| getExpr(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 24| Type = [CharPointerType] char *
|
||||
# 24| ValueCategory = prvalue
|
||||
# 24| getArgument(1).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 24| Type = [CharPointerType] char *
|
||||
# 24| ValueCategory = prvalue
|
||||
# 24| getExpr(): [C11GenericExpr] _Generic
|
||||
# 24| Type = [ArrayType] char[8]
|
||||
# 24| Value = [C11GenericExpr] unknown
|
||||
# 24| ValueCategory = lvalue
|
||||
# 24| getControllingExpr(): [VariableAccess] f
|
||||
# 24| Type = [PointerType] float ***
|
||||
# 24| ValueCategory = prvalue(load)
|
||||
# 24| getAssociationType(0): [TypeName] int
|
||||
# 24| Type = [IntType] int
|
||||
# 24| ValueCategory = prvalue
|
||||
# 24| getAssociationExpr(0): int
|
||||
# 24| Type = [ArrayType] char[4]
|
||||
# 24| Value = [StringLiteral] "int"
|
||||
# 24| ValueCategory = lvalue
|
||||
# 24| getAssociationType(1): [TypeName] const char *
|
||||
# 24| Type = [PointerType] const char *
|
||||
# 24| ValueCategory = prvalue
|
||||
# 24| getAssociationExpr(1): string
|
||||
# 24| Type = [ArrayType] char[7]
|
||||
# 24| Value = [StringLiteral] "string"
|
||||
# 24| ValueCategory = lvalue
|
||||
# 24| getAssociationType(2): [TypeName] void
|
||||
# 24| Type = [VoidType] void
|
||||
# 24| ValueCategory = prvalue
|
||||
# 24| getAssociationExpr(2): [ReuseExpr] reuse of unknown
|
||||
# 24| Type = [ArrayType] char[8]
|
||||
# 24| ValueCategory = lvalue
|
||||
# 24| getControllingExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 24| Type = [PointerType] float ***
|
||||
# 24| ValueCategory = prvalue(load)
|
||||
# 25| getStmt(8): [ReturnStmt] return ...
|
||||
#-----| getExpr(): [Literal] 0
|
||||
#-----| Type = [IntType] int
|
||||
#-----| Value = [Literal] 0
|
||||
#-----| ValueCategory = prvalue
|
||||
generic.cpp:
|
||||
# 4| [FormattingFunction,TopLevelFunction] int printf(char const*)
|
||||
# 4| <params>:
|
||||
# 4| getParameter(0): [Parameter] format
|
||||
# 4| Type = [PointerType] const char *
|
||||
# 15| [TopLevelFunction] int main()
|
||||
# 15| <params>:
|
||||
# 16| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 17| getStmt(0): [DeclStmt] declaration
|
||||
# 17| getDeclarationEntry(0): [VariableDeclarationEntry] definition of i
|
||||
# 17| Type = [IntType] int
|
||||
# 18| getStmt(1): [DeclStmt] declaration
|
||||
# 18| getDeclarationEntry(0): [VariableDeclarationEntry] definition of m
|
||||
# 18| Type = [CTypedefType] MYINT
|
||||
# 19| getStmt(2): [DeclStmt] declaration
|
||||
# 19| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s
|
||||
# 19| Type = [PointerType] const char *
|
||||
# 20| getStmt(3): [DeclStmt] declaration
|
||||
# 20| getDeclarationEntry(0): [VariableDeclarationEntry] definition of f
|
||||
# 20| Type = [PointerType] float ***
|
||||
# 22| getStmt(4): [ExprStmt] ExprStmt
|
||||
# 22| getExpr(): [FormattingFunctionCall,FunctionCall] call to printf
|
||||
# 22| Type = [IntType] int
|
||||
# 22| ValueCategory = prvalue
|
||||
# 22| getArgument(0): i is %s\n
|
||||
# 22| Type = [ArrayType] const char[9]
|
||||
# 22| Value = [StringLiteral] "i is %s\n"
|
||||
# 22| ValueCategory = lvalue
|
||||
# 22| getArgument(1): int
|
||||
# 22| Type = [ArrayType] const char[4]
|
||||
# 22| Value = [StringLiteral] "int"
|
||||
# 22| ValueCategory = lvalue
|
||||
# 22| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 22| Type = [PointerType] const char *
|
||||
# 22| ValueCategory = prvalue
|
||||
# 22| getArgument(1).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 22| Type = [PointerType] const char *
|
||||
# 22| ValueCategory = prvalue
|
||||
# 22| getExpr(): [C11GenericExpr] _Generic
|
||||
# 22| Type = [ArrayType] const char[4]
|
||||
# 22| Value = [C11GenericExpr] int
|
||||
# 22| ValueCategory = lvalue
|
||||
# 22| getControllingExpr(): [VariableAccess] i
|
||||
# 22| Type = [IntType] int
|
||||
# 22| ValueCategory = lvalue
|
||||
# 22| getAssociationType(0): [TypeName] int
|
||||
# 22| Type = [IntType] int
|
||||
# 22| ValueCategory = prvalue
|
||||
# 22| getAssociationExpr(0): [ReuseExpr] reuse of int
|
||||
# 22| Type = [ArrayType] const char[4]
|
||||
# 22| ValueCategory = lvalue
|
||||
# 22| getAssociationType(1): [TypeName] const char *
|
||||
# 22| Type = [PointerType] const char *
|
||||
# 22| ValueCategory = prvalue
|
||||
# 22| getAssociationExpr(1): string
|
||||
# 22| Type = [ArrayType] const char[7]
|
||||
# 22| Value = [StringLiteral] "string"
|
||||
# 22| ValueCategory = lvalue
|
||||
# 22| getAssociationType(2): [TypeName] void
|
||||
# 22| Type = [VoidType] void
|
||||
# 22| ValueCategory = prvalue
|
||||
# 22| getAssociationExpr(2): unknown
|
||||
# 22| Type = [ArrayType] const char[8]
|
||||
# 22| Value = [StringLiteral] "unknown"
|
||||
# 22| ValueCategory = lvalue
|
||||
# 22| getControllingExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 22| Type = [IntType] int
|
||||
# 22| ValueCategory = lvalue
|
||||
# 23| getStmt(5): [ExprStmt] ExprStmt
|
||||
# 23| getExpr(): [FormattingFunctionCall,FunctionCall] call to printf
|
||||
# 23| Type = [IntType] int
|
||||
# 23| ValueCategory = prvalue
|
||||
# 23| getArgument(0): c is %s\n
|
||||
# 23| Type = [ArrayType] const char[9]
|
||||
# 23| Value = [StringLiteral] "c is %s\n"
|
||||
# 23| ValueCategory = lvalue
|
||||
# 23| getArgument(1): int
|
||||
# 23| Type = [ArrayType] const char[4]
|
||||
# 23| Value = [StringLiteral] "int"
|
||||
# 23| ValueCategory = lvalue
|
||||
# 23| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 23| Type = [PointerType] const char *
|
||||
# 23| ValueCategory = prvalue
|
||||
# 23| getArgument(1).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 23| Type = [PointerType] const char *
|
||||
# 23| ValueCategory = prvalue
|
||||
# 23| getExpr(): [C11GenericExpr] _Generic
|
||||
# 23| Type = [ArrayType] const char[4]
|
||||
# 23| Value = [C11GenericExpr] int
|
||||
# 23| ValueCategory = lvalue
|
||||
# 23| getControllingExpr(): [VariableAccess] m
|
||||
# 23| Type = [CTypedefType] MYINT
|
||||
# 23| ValueCategory = lvalue
|
||||
# 23| getAssociationType(0): [TypeName] int
|
||||
# 23| Type = [IntType] int
|
||||
# 23| ValueCategory = prvalue
|
||||
# 23| getAssociationExpr(0): [ReuseExpr] reuse of int
|
||||
# 23| Type = [ArrayType] const char[4]
|
||||
# 23| ValueCategory = lvalue
|
||||
# 23| getAssociationType(1): [TypeName] const char *
|
||||
# 23| Type = [PointerType] const char *
|
||||
# 23| ValueCategory = prvalue
|
||||
# 23| getAssociationExpr(1): string
|
||||
# 23| Type = [ArrayType] const char[7]
|
||||
# 23| Value = [StringLiteral] "string"
|
||||
# 23| ValueCategory = lvalue
|
||||
# 23| getAssociationType(2): [TypeName] void
|
||||
# 23| Type = [VoidType] void
|
||||
# 23| ValueCategory = prvalue
|
||||
# 23| getAssociationExpr(2): unknown
|
||||
# 23| Type = [ArrayType] const char[8]
|
||||
# 23| Value = [StringLiteral] "unknown"
|
||||
# 23| ValueCategory = lvalue
|
||||
# 23| getControllingExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 23| Type = [CTypedefType] MYINT
|
||||
# 23| ValueCategory = lvalue
|
||||
# 24| getStmt(6): [ExprStmt] ExprStmt
|
||||
# 24| getExpr(): [FormattingFunctionCall,FunctionCall] call to printf
|
||||
# 24| Type = [IntType] int
|
||||
# 24| ValueCategory = prvalue
|
||||
# 24| getArgument(0): s is %s\n
|
||||
# 24| Type = [ArrayType] const char[9]
|
||||
# 24| Value = [StringLiteral] "s is %s\n"
|
||||
# 24| ValueCategory = lvalue
|
||||
# 24| getArgument(1): string
|
||||
# 24| Type = [ArrayType] const char[7]
|
||||
# 24| Value = [StringLiteral] "string"
|
||||
# 24| ValueCategory = lvalue
|
||||
# 24| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 24| Type = [PointerType] const char *
|
||||
# 24| ValueCategory = prvalue
|
||||
# 24| getArgument(1).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 24| Type = [PointerType] const char *
|
||||
# 24| ValueCategory = prvalue
|
||||
# 24| getExpr(): [C11GenericExpr] _Generic
|
||||
# 24| Type = [ArrayType] const char[7]
|
||||
# 24| Value = [C11GenericExpr] string
|
||||
# 24| ValueCategory = lvalue
|
||||
# 24| getControllingExpr(): [VariableAccess] s
|
||||
# 24| Type = [PointerType] const char *
|
||||
# 24| ValueCategory = lvalue
|
||||
# 24| getAssociationType(0): [TypeName] int
|
||||
# 24| Type = [IntType] int
|
||||
# 24| ValueCategory = prvalue
|
||||
# 24| getAssociationExpr(0): int
|
||||
# 24| Type = [ArrayType] const char[4]
|
||||
# 24| Value = [StringLiteral] "int"
|
||||
# 24| ValueCategory = lvalue
|
||||
# 24| getAssociationType(1): [TypeName] const char *
|
||||
# 24| Type = [PointerType] const char *
|
||||
# 24| ValueCategory = prvalue
|
||||
# 24| getAssociationExpr(1): [ReuseExpr] reuse of string
|
||||
# 24| Type = [ArrayType] const char[7]
|
||||
# 24| ValueCategory = lvalue
|
||||
# 24| getAssociationType(2): [TypeName] void
|
||||
# 24| Type = [VoidType] void
|
||||
# 24| ValueCategory = prvalue
|
||||
# 24| getAssociationExpr(2): unknown
|
||||
# 24| Type = [ArrayType] const char[8]
|
||||
# 24| Value = [StringLiteral] "unknown"
|
||||
# 24| ValueCategory = lvalue
|
||||
# 24| getControllingExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 24| Type = [PointerType] const char *
|
||||
# 24| ValueCategory = lvalue
|
||||
# 25| getStmt(7): [ExprStmt] ExprStmt
|
||||
# 25| getExpr(): [FormattingFunctionCall,FunctionCall] call to printf
|
||||
# 25| Type = [IntType] int
|
||||
# 25| ValueCategory = prvalue
|
||||
# 25| getArgument(0): f is %s\n
|
||||
# 25| Type = [ArrayType] const char[9]
|
||||
# 25| Value = [StringLiteral] "f is %s\n"
|
||||
# 25| ValueCategory = lvalue
|
||||
# 25| getArgument(1): unknown
|
||||
# 25| Type = [ArrayType] const char[8]
|
||||
# 25| Value = [StringLiteral] "unknown"
|
||||
# 25| ValueCategory = lvalue
|
||||
# 25| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 25| Type = [PointerType] const char *
|
||||
# 25| ValueCategory = prvalue
|
||||
# 25| getArgument(1).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 25| Type = [PointerType] const char *
|
||||
# 25| ValueCategory = prvalue
|
||||
# 25| getExpr(): [C11GenericExpr] _Generic
|
||||
# 25| Type = [ArrayType] const char[8]
|
||||
# 25| Value = [C11GenericExpr] unknown
|
||||
# 25| ValueCategory = lvalue
|
||||
# 25| getControllingExpr(): [VariableAccess] f
|
||||
# 25| Type = [PointerType] float ***
|
||||
# 25| ValueCategory = lvalue
|
||||
# 25| getAssociationType(0): [TypeName] int
|
||||
# 25| Type = [IntType] int
|
||||
# 25| ValueCategory = prvalue
|
||||
# 25| getAssociationExpr(0): int
|
||||
# 25| Type = [ArrayType] const char[4]
|
||||
# 25| Value = [StringLiteral] "int"
|
||||
# 25| ValueCategory = lvalue
|
||||
# 25| getAssociationType(1): [TypeName] const char *
|
||||
# 25| Type = [PointerType] const char *
|
||||
# 25| ValueCategory = prvalue
|
||||
# 25| getAssociationExpr(1): string
|
||||
# 25| Type = [ArrayType] const char[7]
|
||||
# 25| Value = [StringLiteral] "string"
|
||||
# 25| ValueCategory = lvalue
|
||||
# 25| getAssociationType(2): [TypeName] void
|
||||
# 25| Type = [VoidType] void
|
||||
# 25| ValueCategory = prvalue
|
||||
# 25| getAssociationExpr(2): [ReuseExpr] reuse of unknown
|
||||
# 25| Type = [ArrayType] const char[8]
|
||||
# 25| ValueCategory = lvalue
|
||||
# 25| getControllingExpr().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 25| Type = [PointerType] float ***
|
||||
# 25| ValueCategory = lvalue
|
||||
# 26| getStmt(8): [ReturnStmt] return ...
|
||||
#-----| getExpr(): [Literal] 0
|
||||
#-----| Type = [IntType] int
|
||||
#-----| Value = [Literal] 0
|
||||
#-----| ValueCategory = prvalue
|
||||
1
cpp/ql/test/library-tests/c11_generic/PrintAST.qlref
Normal file
1
cpp/ql/test/library-tests/c11_generic/PrintAST.qlref
Normal file
@@ -0,0 +1 @@
|
||||
semmle/code/cpp/PrintAST.ql
|
||||
@@ -0,0 +1,8 @@
|
||||
| generic.c:21:22:21:32 | _Generic | generic.c:21:22:21:32 | describe(val) |
|
||||
| generic.c:22:22:22:32 | _Generic | generic.c:22:22:22:32 | describe(val) |
|
||||
| generic.c:23:22:23:32 | _Generic | generic.c:23:22:23:32 | describe(val) |
|
||||
| generic.c:24:22:24:32 | _Generic | generic.c:24:22:24:32 | describe(val) |
|
||||
| generic.cpp:22:22:22:32 | _Generic | generic.cpp:22:22:22:32 | describe(val) |
|
||||
| generic.cpp:23:22:23:32 | _Generic | generic.cpp:23:22:23:32 | describe(val) |
|
||||
| generic.cpp:24:22:24:32 | _Generic | generic.cpp:24:22:24:32 | describe(val) |
|
||||
| generic.cpp:25:22:25:32 | _Generic | generic.cpp:25:22:25:32 | describe(val) |
|
||||
@@ -0,0 +1,5 @@
|
||||
import cpp
|
||||
|
||||
from C11GenericExpr g, MacroInvocation m
|
||||
where m.getAnExpandedElement() = g
|
||||
select g, m
|
||||
@@ -33,7 +33,7 @@ argHasPostUpdate
|
||||
| test.cpp:67:29:67:35 | source1 | ArgumentNode is missing PostUpdateNode. |
|
||||
| test.cpp:813:19:813:35 | * ... | ArgumentNode is missing PostUpdateNode. |
|
||||
| test.cpp:848:23:848:25 | rpx | ArgumentNode is missing PostUpdateNode. |
|
||||
| test.cpp:1057:19:1057:21 | * ... | ArgumentNode is missing PostUpdateNode. |
|
||||
| test.cpp:1093:19:1093:21 | * ... | ArgumentNode is missing PostUpdateNode. |
|
||||
postWithInFlow
|
||||
| BarrierGuard.cpp:49:6:49:6 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| BarrierGuard.cpp:60:7:60:7 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -167,15 +167,17 @@ postWithInFlow
|
||||
| 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. |
|
||||
| test.cpp:1045:9:1045:11 | ref arg buf | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1051:5:1051:11 | content [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1052:9:1052:9 | a [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1056:5:1056:7 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1056:6:1056:7 | pp [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1062:53:1062:53 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1072:3:1072:4 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1072:4:1072:4 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1073:3:1073:4 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1073:4:1073:4 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1066:5:1066:5 | i [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1069:5:1069:5 | i [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1087:5:1087:11 | content [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1088:9:1088:9 | a [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1092:5:1092:7 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1092:6:1092:7 | pp [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1098:53:1098:53 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1108:3:1108:4 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1108:4:1108:4 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1109:3:1109:4 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:1109:4:1109:4 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user