mirror of
https://github.com/github/codeql.git
synced 2026-04-23 07:45:17 +02:00
Merge remote-tracking branch 'mathiasvp/final-alias-edge-kind' into brodes/seh_flow_phase2_splitting_seh_edges
# Conflicts: # cpp/ql/lib/semmle/code/cpp/ir/implementation/EdgeKind.qll
This commit is contained in:
@@ -1,3 +1,13 @@
|
||||
## 3.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Deleted the old deprecated data flow API that was based on extending a configuration class. See https://github.blog/changelog/2023-08-14-new-dataflow-api-for-writing-custom-codeql-queries for instructions on migrating your queries to use the new API.
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `NonThrowing` class (`semmle.code.cpp.models.interfaces.NonThrowing`) has been deprecated. Please use the `NonCppThrowingFunction` class instead.
|
||||
|
||||
## 2.1.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
* The `NonThrowing` class (`semmle.code.cpp.models.interfaces.NonThrowing`) has been deprecated. Please use the `NonCppThrowingFunction` class instead.
|
||||
@@ -1,4 +1,9 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
## 3.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Deleted the old deprecated data flow API that was based on extending a configuration class. See https://github.blog/changelog/2023-08-14-new-dataflow-api-for-writing-custom-codeql-queries for instructions on migrating your queries to use the new API.
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `NonThrowing` class (`semmle.code.cpp.models.interfaces.NonThrowing`) has been deprecated. Please use the `NonCppThrowingFunction` class instead.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 2.1.1
|
||||
lastReleaseVersion: 3.0.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 2.1.2-dev
|
||||
version: 3.0.1-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -3,13 +3,12 @@
|
||||
*/
|
||||
|
||||
private import internal.EdgeKindInternal
|
||||
private import codeql.util.Boolean
|
||||
|
||||
private newtype TEdgeKind =
|
||||
TGotoEdge() or // Single successor (including fall-through)
|
||||
TTrueEdge() or // 'true' edge of conditional branch
|
||||
TFalseEdge() or // 'false' edge of conditional branch
|
||||
TExceptionEdge(Boolean isSeh) or // Thrown exception, true for SEH exceptions, false otherwise
|
||||
TExceptionEdge() or // Thrown exception
|
||||
TDefaultEdge() or // 'default' label of switch
|
||||
TCaseEdge(string minValue, string maxValue) {
|
||||
// Case label of switch
|
||||
@@ -21,16 +20,18 @@ private newtype TEdgeKind =
|
||||
* `Instruction` or `IRBlock` has at most one successor of any single
|
||||
* `EdgeKind`.
|
||||
*/
|
||||
abstract class EdgeKind extends TEdgeKind {
|
||||
abstract private class EdgeKindImpl extends TEdgeKind {
|
||||
/** Gets a textual representation of this edge kind. */
|
||||
abstract string toString();
|
||||
}
|
||||
|
||||
final class EdgeKind = EdgeKindImpl;
|
||||
|
||||
/**
|
||||
* A "goto" edge, representing the unconditional successor of an `Instruction`
|
||||
* or `IRBlock`.
|
||||
*/
|
||||
class GotoEdge extends EdgeKind, TGotoEdge {
|
||||
class GotoEdge extends EdgeKindImpl, TGotoEdge {
|
||||
final override string toString() { result = "Goto" }
|
||||
}
|
||||
|
||||
@@ -38,7 +39,7 @@ class GotoEdge extends EdgeKind, TGotoEdge {
|
||||
* A "true" edge, representing the successor of a conditional branch when the
|
||||
* condition is non-zero.
|
||||
*/
|
||||
class TrueEdge extends EdgeKind, TTrueEdge {
|
||||
class TrueEdge extends EdgeKindImpl, TTrueEdge {
|
||||
final override string toString() { result = "True" }
|
||||
}
|
||||
|
||||
@@ -46,7 +47,7 @@ class TrueEdge extends EdgeKind, TTrueEdge {
|
||||
* A "false" edge, representing the successor of a conditional branch when the
|
||||
* condition is zero.
|
||||
*/
|
||||
class FalseEdge extends EdgeKind, TFalseEdge {
|
||||
class FalseEdge extends EdgeKindImpl, TFalseEdge {
|
||||
final override string toString() { result = "False" }
|
||||
}
|
||||
|
||||
@@ -54,26 +55,15 @@ class FalseEdge extends EdgeKind, TFalseEdge {
|
||||
* An "exception" edge, representing the successor of an instruction when that
|
||||
* instruction's evaluation throws an exception.
|
||||
*/
|
||||
class ExceptionEdge extends EdgeKind, TExceptionEdge {
|
||||
Boolean isSeh; //true for Structured Exception Handling, false for C++ exceptions
|
||||
|
||||
ExceptionEdge() { this = TExceptionEdge(isSeh) }
|
||||
|
||||
/**
|
||||
* Holds if the exception is a Structured Exception Handling (SEH) exception.
|
||||
*/
|
||||
final predicate isSeh() { isSeh = true }
|
||||
|
||||
final override string toString() {
|
||||
if isSeh = true then result = "SEH Exception" else result = "C++ Exception"
|
||||
}
|
||||
class ExceptionEdge extends EdgeKindImpl, TExceptionEdge {
|
||||
final override string toString() { result = "Exception" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A "default" edge, representing the successor of a `Switch` instruction when
|
||||
* none of the case values matches the condition value.
|
||||
*/
|
||||
class DefaultEdge extends EdgeKind, TDefaultEdge {
|
||||
class DefaultEdge extends EdgeKindImpl, TDefaultEdge {
|
||||
final override string toString() { result = "Default" }
|
||||
}
|
||||
|
||||
@@ -81,7 +71,7 @@ class DefaultEdge extends EdgeKind, TDefaultEdge {
|
||||
* A "case" edge, representing the successor of a `Switch` instruction when the
|
||||
* the condition value matches a corresponding `case` label.
|
||||
*/
|
||||
class CaseEdge extends EdgeKind, TCaseEdge {
|
||||
class CaseEdge extends EdgeKindImpl, TCaseEdge {
|
||||
string minValue;
|
||||
string maxValue;
|
||||
|
||||
@@ -134,10 +124,8 @@ module EdgeKind {
|
||||
|
||||
/**
|
||||
* Gets the single instance of the `ExceptionEdge` class.
|
||||
* Gets the instance of the `ExceptionEdge` class.
|
||||
* `isSeh` is true if the exception is an SEH exception, and false for a C++ edge.
|
||||
*/
|
||||
ExceptionEdge exceptionEdge(Boolean isSeh) { result = TExceptionEdge(isSeh) }
|
||||
ExceptionEdge exceptionEdge() { result = TExceptionEdge() }
|
||||
|
||||
/**
|
||||
* Gets the single instance of the `DefaultEdge` class.
|
||||
|
||||
@@ -27,8 +27,12 @@ predicate blockContainsPreprocessorBranches(BasicBlock bb) {
|
||||
)
|
||||
}
|
||||
|
||||
from GuardCondition gc, FreeCall fc, Variable v, BasicBlock bb
|
||||
where
|
||||
/**
|
||||
* Holds if `gc` ensures that `v` is non-zero when reaching `bb`, and `bb`
|
||||
* contains a single statement which is `fc`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate interesting(GuardCondition gc, FreeCall fc, Variable v, BasicBlock bb) {
|
||||
gc.ensuresEq(v.getAnAccess(), 0, bb, false) and
|
||||
fc.getArgument(0) = v.getAnAccess() and
|
||||
bb = fc.getBasicBlock() and
|
||||
@@ -39,9 +43,21 @@ where
|
||||
// Block statement with a single nested statement: if (x) { free(x); }
|
||||
strictcount(bb.(BlockStmt).getAStmt()) = 1
|
||||
) and
|
||||
strictcount(BasicBlock bb2 | gc.ensuresEq(_, 0, bb2, _) | bb2) = 1 and
|
||||
not fc.isInMacroExpansion() and
|
||||
not blockContainsPreprocessorBranches(bb) and
|
||||
not (gc instanceof BinaryOperation and not gc instanceof ComparisonOperation) and
|
||||
not exists(CommaExpr c | c.getAChild*() = fc)
|
||||
}
|
||||
|
||||
/** Holds if `gc` only guards a single block. */
|
||||
bindingset[gc]
|
||||
pragma[inline_late]
|
||||
private predicate guardConditionGuardsUniqueBlock(GuardCondition gc) {
|
||||
strictcount(BasicBlock bb | gc.ensuresEq(_, 0, bb, _)) = 1
|
||||
}
|
||||
|
||||
from GuardCondition gc, FreeCall fc, Variable v, BasicBlock bb
|
||||
where
|
||||
interesting(gc, fc, v, bb) and
|
||||
guardConditionGuardsUniqueBlock(gc)
|
||||
select gc, "unnecessary NULL check before call to $@", fc, "free"
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
## 1.3.0
|
||||
|
||||
### New Queries
|
||||
|
||||
* Added a new high-precision quality query, `cpp/guarded-free`, which detects useless NULL pointer checks before calls to `free`. A variation of this query was originally contributed as an [experimental query by @mario-campos](https://github.com/github/codeql/pull/16331).
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Call to function with fewer arguments than declared parameters" query (`cpp/too-few-arguments`) query no longer produces results if the function has been implicitly declared.
|
||||
|
||||
## 1.2.7
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The "Call to function with fewer arguments than declared parameters" query (`cpp/too-few-arguments`) query no longer produces results if the function has been implicitly declared.
|
||||
@@ -1,4 +1,9 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
## 1.3.0
|
||||
|
||||
### New Queries
|
||||
|
||||
* Added a new high-precision quality query, `cpp/guarded-free`, which detects useless NULL pointer checks before calls to `free`. A variation of this query was originally contributed as an [experimental query by @mario-campos](https://github.com/github/codeql/pull/16331).
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Call to function with fewer arguments than declared parameters" query (`cpp/too-few-arguments`) query no longer produces results if the function has been implicitly declared.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.2.7
|
||||
lastReleaseVersion: 1.3.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 1.2.8-dev
|
||||
version: 1.3.1-dev
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
Reference in New Issue
Block a user