mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge branch 'main' into remove-conflation-from-out-nodes
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
- description: Extended and experimental security queries for GitHub Actions
|
||||
- import: codeql-suites/actions-code-scanning.qls
|
||||
2429
cpp/downgrades/1aa71a4a687fc93f807d4dfeeef70feceeced242/old.dbscheme
Normal file
2429
cpp/downgrades/1aa71a4a687fc93f807d4dfeeef70feceeced242/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,17 @@
|
||||
class Stmt extends @stmt {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Location extends @location_stmt {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
predicate isConstevalIf(Stmt stmt) {
|
||||
exists(int kind | stmts(stmt, kind, _) | kind = 38 or kind = 39)
|
||||
}
|
||||
|
||||
from Stmt stmt, int kind, int kind_new, Location location
|
||||
where
|
||||
stmts(stmt, kind, location) and
|
||||
if isConstevalIf(stmt) then kind_new = 7 else kind_new = kind // Turns consteval if into a block with two block statements in it
|
||||
select stmt, kind_new, location
|
||||
@@ -0,0 +1,5 @@
|
||||
description: Support (not) consteval if
|
||||
compatibility: full
|
||||
consteval_if_then.rel: delete
|
||||
consteval_if_else.rel: delete
|
||||
stmts.rel: run stmts.qlo
|
||||
4
cpp/ql/lib/change-notes/2024-01-16-consteval-if.md
Normal file
4
cpp/ql/lib/change-notes/2024-01-16-consteval-if.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* A new class `ConstevalIfStmt` was introduced, which represents the C++23 `if consteval` and `if ! consteval` statements.
|
||||
@@ -912,6 +912,10 @@ private predicate namedStmtChildPredicates(Locatable s, Element e, string pred)
|
||||
or
|
||||
s.(ConstexprIfStmt).getElse() = e and pred = "getElse()"
|
||||
or
|
||||
s.(ConstevalIfStmt).getThen() = e and pred = "getThen()"
|
||||
or
|
||||
s.(ConstevalIfStmt).getElse() = e and pred = "getElse()"
|
||||
or
|
||||
s.(Handler).getParameter() = e and pred = "getParameter()"
|
||||
or
|
||||
s.(IfStmt).getInitialization() = e and pred = "getInitialization()"
|
||||
|
||||
@@ -876,6 +876,25 @@ private predicate subEdge(Pos p1, Node n1, Node n2, Pos p2) {
|
||||
p2.nodeAfter(n2, s)
|
||||
)
|
||||
or
|
||||
// NotConstevalIfStmt -> { then, else } ->
|
||||
exists(ConstevalIfStmt s |
|
||||
p1.nodeAt(n1, s) and
|
||||
p2.nodeBefore(n2, s.getThen())
|
||||
or
|
||||
p1.nodeAt(n1, s) and
|
||||
p2.nodeBefore(n2, s.getElse())
|
||||
or
|
||||
p1.nodeAt(n1, s) and
|
||||
not exists(s.getElse()) and
|
||||
p2.nodeAfter(n2, s)
|
||||
or
|
||||
p1.nodeAfter(n1, s.getThen()) and
|
||||
p2.nodeAfter(n2, s)
|
||||
or
|
||||
p1.nodeAfter(n1, s.getElse()) and
|
||||
p2.nodeAfter(n2, s)
|
||||
)
|
||||
or
|
||||
// WhileStmt -> condition ; body -> condition ; after dtors -> after
|
||||
exists(WhileStmt s |
|
||||
p1.nodeAt(n1, s) and
|
||||
|
||||
@@ -47,7 +47,7 @@ abstract class TranslatedFlexibleCondition extends TranslatedCondition, Conditio
|
||||
{
|
||||
TranslatedFlexibleCondition() { this = TTranslatedFlexibleCondition(expr) }
|
||||
|
||||
final override predicate handlesDestructorsExplicitly() { none() } // TODO: this needs to be revisted when we get unnamed destructors
|
||||
final override predicate handlesDestructorsExplicitly() { none() } // TODO: this needs to be revisited when we get unnamed destructors
|
||||
|
||||
final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
|
||||
|
||||
|
||||
@@ -166,7 +166,7 @@ private predicate ignoreExpr(Expr expr) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the side effects of `expr` should be ignoredf for the purposes of IR generation.
|
||||
* Holds if the side effects of `expr` should be ignored for the purposes of IR generation.
|
||||
*
|
||||
* In cases involving `constexpr`, a call can wind up as a constant expression. `ignoreExpr()` will
|
||||
* not hold for such a call, since we do need to translate the call (as a constant), but we need to
|
||||
|
||||
@@ -1098,6 +1098,61 @@ class TranslatedConstExprIfStmt extends TranslatedIfLikeStmt {
|
||||
override predicate hasElse() { exists(stmt.getElse()) }
|
||||
}
|
||||
|
||||
class TranslatedConstevalIfStmt extends TranslatedStmt {
|
||||
override ConstevalIfStmt stmt;
|
||||
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
if not this.hasEvaluatedBranch()
|
||||
then
|
||||
kind instanceof GotoEdge and
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
else result = this.getEvaluatedBranch().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and
|
||||
result = this.getThen()
|
||||
or
|
||||
id = 1 and
|
||||
result = this.getElse()
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
not this.hasEvaluatedBranch() and
|
||||
opcode instanceof Opcode::NoOp and
|
||||
tag = OnlyInstructionTag() and
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
if not this.hasEvaluatedBranch()
|
||||
then result = this.getInstruction(OnlyInstructionTag())
|
||||
else result = this.getEvaluatedBranch().getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getEvaluatedBranch() }
|
||||
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
(child = this.getThen() or child = this.getElse()) and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
TranslatedStmt getEvaluatedBranch() {
|
||||
result = getTranslatedStmt(stmt.getRuntimeEvaluatedBranch())
|
||||
}
|
||||
|
||||
predicate hasEvaluatedBranch() { stmt.hasRuntimeEvaluatedBranch() }
|
||||
|
||||
TranslatedStmt getThen() { result = getTranslatedStmt(stmt.getThen()) }
|
||||
|
||||
TranslatedStmt getElse() { result = getTranslatedStmt(stmt.getElse()) }
|
||||
}
|
||||
|
||||
abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
|
||||
override Loop stmt;
|
||||
|
||||
|
||||
@@ -437,6 +437,154 @@ class ConstexprIfStmt extends ConditionalStmt, @stmt_constexpr_if {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ '(not) consteval if'. For example, the `if consteval` statement
|
||||
* in the following code:
|
||||
* ```cpp
|
||||
* if consteval {
|
||||
* ...
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class ConstevalIfStmt extends Stmt, @stmt_consteval_or_not_consteval_if {
|
||||
override string getAPrimaryQlClass() { result = "ConstevalIfStmt" }
|
||||
|
||||
override string toString() {
|
||||
if this.isNot() then result = "if ! consteval ..." else result = "if consteval ..."
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this is a 'not consteval if' statement.
|
||||
*
|
||||
* For example, this holds for
|
||||
* ```cpp
|
||||
* if ! consteval { return true; }
|
||||
* ```
|
||||
* but not for
|
||||
* ```cpp
|
||||
* if consteval { return true; }
|
||||
* ```
|
||||
*/
|
||||
predicate isNot() { this instanceof @stmt_not_consteval_if }
|
||||
|
||||
/**
|
||||
* Gets the 'then' statement of this '(not) consteval if' statement.
|
||||
*
|
||||
* For example, for
|
||||
* ```cpp
|
||||
* if consteval { return true; }
|
||||
* ```
|
||||
* the result is the `BlockStmt` `{ return true; }`.
|
||||
*/
|
||||
Stmt getThen() { consteval_if_then(underlyingElement(this), unresolveElement(result)) }
|
||||
|
||||
/**
|
||||
* Gets the 'else' statement of this '(not) constexpr if' statement, if any.
|
||||
*
|
||||
* For example, for
|
||||
* ```cpp
|
||||
* if consteval { return true; } else { return false; }
|
||||
* ```
|
||||
* the result is the `BlockStmt` `{ return false; }`, and for
|
||||
* ```cpp
|
||||
* if consteval { return true; }
|
||||
* ```
|
||||
* there is no result.
|
||||
*/
|
||||
Stmt getElse() { consteval_if_else(underlyingElement(this), unresolveElement(result)) }
|
||||
|
||||
/**
|
||||
* Holds if this '(not) constexpr if' statement has an 'else' statement.
|
||||
*
|
||||
* For example, this holds for
|
||||
* ```cpp
|
||||
* if consteval { return true; } else { return false; }
|
||||
* ```
|
||||
* but not for
|
||||
* ```cpp
|
||||
* if consteval { return true; }
|
||||
* ```
|
||||
*/
|
||||
predicate hasElse() { exists(this.getElse()) }
|
||||
|
||||
override predicate mayBeImpure() {
|
||||
this.getThen().mayBeImpure() or
|
||||
this.getElse().mayBeImpure()
|
||||
}
|
||||
|
||||
override predicate mayBeGloballyImpure() {
|
||||
this.getThen().mayBeGloballyImpure() or
|
||||
this.getElse().mayBeGloballyImpure()
|
||||
}
|
||||
|
||||
override MacroInvocation getGeneratingMacro() {
|
||||
this.getThen().getGeneratingMacro() = result and
|
||||
(this.hasElse() implies this.getElse().getGeneratingMacro() = result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the statement of this '(not) consteval if' statement evaluated during compile time, if any.
|
||||
*
|
||||
* For example, for
|
||||
* ```cpp
|
||||
* if ! consteval { return true; } else { return false; }
|
||||
* ```
|
||||
* the result is the `BlockStmt` `{ return false; }`, and for
|
||||
* ```cpp
|
||||
* if ! consteval { return true; }
|
||||
* ```
|
||||
* there is no result.
|
||||
*/
|
||||
Stmt getCompileTimeEvaluatedBranch() {
|
||||
if this.isNot() then result = this.getElse() else result = this.getThen()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this '(not) constexpr if' statement has a compile time evaluated statement.
|
||||
*
|
||||
* For example, this holds for
|
||||
* ```cpp
|
||||
* if ! consteval { return true; } else { return false; }
|
||||
* ```
|
||||
* but not for
|
||||
* ```cpp
|
||||
* if ! consteval { return true; }
|
||||
* ```
|
||||
*/
|
||||
predicate hasCompileTimeEvaluatedBranch() { exists(this.getCompileTimeEvaluatedBranch()) }
|
||||
|
||||
/**
|
||||
* Gets the statement of this '(not) consteval if' statement evaluated during runtime, if any.
|
||||
*
|
||||
* For example, for
|
||||
* ```cpp
|
||||
* if consteval { return true; } else { return false; }
|
||||
* ```
|
||||
* the result is the `BlockStmt` `{ return false; }`, and for
|
||||
* ```cpp
|
||||
* if consteval { return true; }
|
||||
* ```
|
||||
* there is no result.
|
||||
*/
|
||||
Stmt getRuntimeEvaluatedBranch() {
|
||||
if this.isNot() then result = this.getThen() else result = this.getElse()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this '(not) constexpr if' statement has a runtime evaluated statement.
|
||||
*
|
||||
* For example, this holds for
|
||||
* ```cpp
|
||||
* if consteval { return true; } else { return false; }
|
||||
* ```
|
||||
* but not for
|
||||
* ```cpp
|
||||
* if consteval { return true; }
|
||||
* ```
|
||||
*/
|
||||
predicate hasRuntimeEvaluatedBranch() { exists(this.getRuntimeEvaluatedBranch()) }
|
||||
}
|
||||
|
||||
private class TLoop = @stmt_while or @stmt_end_test_while or @stmt_range_based_for or @stmt_for;
|
||||
|
||||
/**
|
||||
|
||||
@@ -2152,6 +2152,8 @@ case @stmt.kind of
|
||||
// ... 34 @stmt_finally_end deprecated
|
||||
| 35 = @stmt_constexpr_if
|
||||
| 37 = @stmt_co_return
|
||||
| 38 = @stmt_consteval_if
|
||||
| 39 = @stmt_not_consteval_if
|
||||
;
|
||||
|
||||
type_vla(
|
||||
@@ -2194,6 +2196,18 @@ constexpr_if_else(
|
||||
int else_id: @stmt ref
|
||||
);
|
||||
|
||||
@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
|
||||
|
||||
consteval_if_then(
|
||||
unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
|
||||
int then_id: @stmt ref
|
||||
);
|
||||
|
||||
consteval_if_else(
|
||||
unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
|
||||
int else_id: @stmt ref
|
||||
);
|
||||
|
||||
while_body(
|
||||
unique int while_stmt: @stmt_while ref,
|
||||
int body_id: @stmt 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: Support (not) consteval if
|
||||
compatibility: partial
|
||||
124
cpp/ql/test/library-tests/consteval_if/cfg.expected
Normal file
124
cpp/ql/test/library-tests/consteval_if/cfg.expected
Normal file
@@ -0,0 +1,124 @@
|
||||
| ClassWithDestructor::ClassWithDestructor | false | 157 | 157 | ClassWithDestructor |
|
||||
| ClassWithDestructor::ClassWithDestructor | false | 296 | 296 | ClassWithDestructor |
|
||||
| ClassWithDestructor::ClassWithDestructor | false | 302 | 302 | ClassWithDestructor |
|
||||
| ClassWithDestructor::operator bool | false | 173 | 173 | operator bool |
|
||||
| ClassWithDestructor::operator= | false | 288 | 288 | operator= |
|
||||
| ClassWithDestructor::~ClassWithDestructor | false | 190 | 190 | ~ClassWithDestructor |
|
||||
| __va_list_tag::operator= | false | 66 | 66 | operator= |
|
||||
| __va_list_tag::operator= | false | 72 | 72 | operator= |
|
||||
| destruction_on_consteval | false | 193 | 193 | destruction_on_consteval |
|
||||
| destruction_on_consteval | false | 198 | 198 | if consteval ... |
|
||||
| destruction_on_consteval | false | 200 | 200 | return ... |
|
||||
| destruction_on_consteval | false | 204 | 204 | 1 |
|
||||
| destruction_on_consteval | false | 205 | 205 | { ... } |
|
||||
| destruction_on_consteval | false | 208 | 208 | call to ClassWithDestructor |
|
||||
| destruction_on_consteval | false | 210 | 210 | initializer for cwd |
|
||||
| destruction_on_consteval | false | 213 | 213 | declaration |
|
||||
| destruction_on_consteval | false | 215 | 215 | return ... |
|
||||
| destruction_on_consteval | false | 218 | 218 | call to operator bool |
|
||||
| destruction_on_consteval | false | 219 | 219 | cwd |
|
||||
| destruction_on_consteval | false | 221 | 221 | (const ClassWithDestructor)... |
|
||||
| destruction_on_consteval | false | 222 | 222 | { ... } |
|
||||
| destruction_on_consteval | false | 224 | 224 | { ... } |
|
||||
| destruction_on_consteval | false | 226 | 226 | cwd |
|
||||
| destruction_on_consteval | false | 228 | 228 | call to cwd.~ClassWithDestructor |
|
||||
| destruction_on_consteval | false | 229 | 229 | cwd |
|
||||
| destruction_on_consteval | false | 230 | 230 | call to cwd.~ClassWithDestructor |
|
||||
| destruction_on_consteval | true | 198 | 205 | |
|
||||
| destruction_on_consteval | true | 198 | 222 | |
|
||||
| destruction_on_consteval | true | 200 | 204 | |
|
||||
| destruction_on_consteval | true | 204 | 193 | |
|
||||
| destruction_on_consteval | true | 205 | 200 | |
|
||||
| destruction_on_consteval | true | 208 | 215 | |
|
||||
| destruction_on_consteval | true | 210 | 208 | |
|
||||
| destruction_on_consteval | true | 213 | 210 | |
|
||||
| destruction_on_consteval | true | 215 | 219 | |
|
||||
| destruction_on_consteval | true | 218 | 226 | |
|
||||
| destruction_on_consteval | true | 219 | 218 | |
|
||||
| destruction_on_consteval | true | 222 | 213 | |
|
||||
| destruction_on_consteval | true | 224 | 198 | |
|
||||
| destruction_on_consteval | true | 226 | 228 | |
|
||||
| destruction_on_consteval | true | 228 | 193 | |
|
||||
| destruction_on_consteval | true | 229 | 230 | |
|
||||
| destruction_on_consteval | true | 230 | 193 | |
|
||||
| destruction_on_consteval2 | false | 147 | 147 | destruction_on_consteval2 |
|
||||
| destruction_on_consteval2 | false | 152 | 152 | declaration |
|
||||
| destruction_on_consteval2 | false | 155 | 155 | call to ClassWithDestructor |
|
||||
| destruction_on_consteval2 | false | 158 | 158 | initializer for cwd |
|
||||
| destruction_on_consteval2 | false | 161 | 161 | if consteval ... |
|
||||
| destruction_on_consteval2 | false | 163 | 163 | return ... |
|
||||
| destruction_on_consteval2 | false | 167 | 167 | 1 |
|
||||
| destruction_on_consteval2 | false | 168 | 168 | { ... } |
|
||||
| destruction_on_consteval2 | false | 170 | 170 | return ... |
|
||||
| destruction_on_consteval2 | false | 178 | 178 | call to operator bool |
|
||||
| destruction_on_consteval2 | false | 179 | 179 | cwd |
|
||||
| destruction_on_consteval2 | false | 182 | 182 | (const ClassWithDestructor)... |
|
||||
| destruction_on_consteval2 | false | 183 | 183 | { ... } |
|
||||
| destruction_on_consteval2 | false | 185 | 185 | { ... } |
|
||||
| destruction_on_consteval2 | false | 187 | 187 | cwd |
|
||||
| destruction_on_consteval2 | false | 189 | 189 | call to cwd.~ClassWithDestructor |
|
||||
| destruction_on_consteval2 | false | 191 | 191 | cwd |
|
||||
| destruction_on_consteval2 | false | 192 | 192 | call to cwd.~ClassWithDestructor |
|
||||
| destruction_on_consteval2 | true | 152 | 158 | |
|
||||
| destruction_on_consteval2 | true | 155 | 161 | |
|
||||
| destruction_on_consteval2 | true | 158 | 155 | |
|
||||
| destruction_on_consteval2 | true | 161 | 168 | |
|
||||
| destruction_on_consteval2 | true | 161 | 183 | |
|
||||
| destruction_on_consteval2 | true | 163 | 167 | |
|
||||
| destruction_on_consteval2 | true | 167 | 187 | |
|
||||
| destruction_on_consteval2 | true | 168 | 163 | |
|
||||
| destruction_on_consteval2 | true | 170 | 179 | |
|
||||
| destruction_on_consteval2 | true | 178 | 191 | |
|
||||
| destruction_on_consteval2 | true | 179 | 178 | |
|
||||
| destruction_on_consteval2 | true | 183 | 170 | |
|
||||
| destruction_on_consteval2 | true | 185 | 152 | |
|
||||
| destruction_on_consteval2 | true | 187 | 189 | |
|
||||
| destruction_on_consteval2 | true | 189 | 147 | |
|
||||
| destruction_on_consteval2 | true | 191 | 192 | |
|
||||
| destruction_on_consteval2 | true | 192 | 147 | |
|
||||
| test | false | 231 | 231 | test |
|
||||
| test | false | 236 | 236 | declaration |
|
||||
| test | false | 241 | 241 | if consteval ... |
|
||||
| test | false | 243 | 243 | ExprStmt |
|
||||
| test | false | 245 | 245 | x |
|
||||
| test | false | 249 | 249 | 1 |
|
||||
| test | false | 250 | 250 | ... = ... |
|
||||
| test | false | 252 | 252 | { ... } |
|
||||
| test | false | 254 | 254 | ExprStmt |
|
||||
| test | false | 256 | 256 | x |
|
||||
| test | false | 260 | 260 | 2 |
|
||||
| test | false | 261 | 261 | ... = ... |
|
||||
| test | false | 263 | 263 | { ... } |
|
||||
| test | false | 265 | 265 | if consteval ... |
|
||||
| test | false | 267 | 267 | ExprStmt |
|
||||
| test | false | 269 | 269 | x |
|
||||
| test | false | 273 | 273 | 3 |
|
||||
| test | false | 274 | 274 | ... = ... |
|
||||
| test | false | 276 | 276 | { ... } |
|
||||
| test | false | 278 | 278 | return ... |
|
||||
| test | false | 280 | 280 | x |
|
||||
| test | false | 282 | 282 | (bool)... |
|
||||
| test | false | 283 | 283 | { ... } |
|
||||
| test | true | 236 | 241 | |
|
||||
| test | true | 241 | 252 | |
|
||||
| test | true | 241 | 263 | |
|
||||
| test | true | 243 | 249 | |
|
||||
| test | true | 245 | 250 | |
|
||||
| test | true | 249 | 245 | |
|
||||
| test | true | 250 | 265 | |
|
||||
| test | true | 252 | 243 | |
|
||||
| test | true | 254 | 260 | |
|
||||
| test | true | 256 | 261 | |
|
||||
| test | true | 260 | 256 | |
|
||||
| test | true | 261 | 265 | |
|
||||
| test | true | 263 | 254 | |
|
||||
| test | true | 265 | 276 | |
|
||||
| test | true | 265 | 278 | |
|
||||
| test | true | 267 | 273 | |
|
||||
| test | true | 269 | 274 | |
|
||||
| test | true | 273 | 269 | |
|
||||
| test | true | 274 | 278 | |
|
||||
| test | true | 276 | 267 | |
|
||||
| test | true | 278 | 280 | |
|
||||
| test | true | 280 | 231 | |
|
||||
| test | true | 283 | 236 | |
|
||||
42
cpp/ql/test/library-tests/consteval_if/cfg.ql
Normal file
42
cpp/ql/test/library-tests/consteval_if/cfg.ql
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* query-type: graph
|
||||
*
|
||||
* @kind graph-equivalence-test
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
class DestructorCallEnhanced extends DestructorCall {
|
||||
override string toString() {
|
||||
if exists(this.getQualifier().(VariableAccess).getTarget().getName())
|
||||
then
|
||||
result =
|
||||
"call to " + this.getQualifier().(VariableAccess).getTarget().getName() + "." +
|
||||
this.getTarget().getName()
|
||||
else result = super.toString()
|
||||
}
|
||||
}
|
||||
|
||||
string scope(ControlFlowNode x) {
|
||||
if exists(x.getControlFlowScope().getQualifiedName())
|
||||
then result = x.getControlFlowScope().getQualifiedName()
|
||||
else result = "<no scope>"
|
||||
}
|
||||
|
||||
predicate isNode(boolean isEdge, ControlFlowNode x, ControlFlowNode y, string label) {
|
||||
isEdge = false and x = y and label = x.toString()
|
||||
}
|
||||
|
||||
predicate isSuccessor(boolean isEdge, ControlFlowNode x, ControlFlowNode y, string label) {
|
||||
exists(string truelabel, string falselabel |
|
||||
isEdge = true and
|
||||
x.getASuccessor() = y and
|
||||
(if x.getATrueSuccessor() = y then truelabel = "T" else truelabel = "") and
|
||||
(if x.getAFalseSuccessor() = y then falselabel = "F" else falselabel = "") and
|
||||
label = truelabel + falselabel
|
||||
)
|
||||
}
|
||||
|
||||
from boolean isEdge, ControlFlowNode x, ControlFlowNode y, string label
|
||||
where isNode(isEdge, x, y, label) or isSuccessor(isEdge, x, y, label)
|
||||
select scope(x), isEdge, x, y, label
|
||||
25
cpp/ql/test/library-tests/consteval_if/stmts.expected
Normal file
25
cpp/ql/test/library-tests/consteval_if/stmts.expected
Normal file
@@ -0,0 +1,25 @@
|
||||
| test.cpp:3:23:14:1 | { ... } |
|
||||
| test.cpp:4:5:4:10 | declaration |
|
||||
| test.cpp:5:5:9:5 | if consteval ... |
|
||||
| test.cpp:5:18:7:5 | { ... } |
|
||||
| test.cpp:6:9:6:14 | ExprStmt |
|
||||
| test.cpp:7:12:9:5 | { ... } |
|
||||
| test.cpp:8:9:8:14 | ExprStmt |
|
||||
| test.cpp:10:5:12:5 | if consteval ... |
|
||||
| test.cpp:10:18:12:5 | { ... } |
|
||||
| test.cpp:11:9:11:14 | ExprStmt |
|
||||
| test.cpp:13:5:13:13 | return ... |
|
||||
| test.cpp:24:33:31:1 | { ... } |
|
||||
| test.cpp:25:3:30:3 | if consteval ... |
|
||||
| test.cpp:25:16:27:3 | { ... } |
|
||||
| test.cpp:26:5:26:16 | return ... |
|
||||
| test.cpp:27:10:30:3 | { ... } |
|
||||
| test.cpp:28:5:28:28 | declaration |
|
||||
| test.cpp:29:5:29:15 | return ... |
|
||||
| test.cpp:33:34:40:1 | { ... } |
|
||||
| test.cpp:34:3:34:26 | declaration |
|
||||
| test.cpp:35:3:39:3 | if consteval ... |
|
||||
| test.cpp:35:16:37:3 | { ... } |
|
||||
| test.cpp:36:5:36:16 | return ... |
|
||||
| test.cpp:37:10:39:3 | { ... } |
|
||||
| test.cpp:38:5:38:15 | return ... |
|
||||
4
cpp/ql/test/library-tests/consteval_if/stmts.ql
Normal file
4
cpp/ql/test/library-tests/consteval_if/stmts.ql
Normal file
@@ -0,0 +1,4 @@
|
||||
import cpp
|
||||
|
||||
from Stmt s
|
||||
select s
|
||||
40
cpp/ql/test/library-tests/consteval_if/test.cpp
Normal file
40
cpp/ql/test/library-tests/consteval_if/test.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
// semmle-extractor-options: -std=c++23
|
||||
|
||||
constexpr bool test() {
|
||||
int x;
|
||||
if consteval {
|
||||
x = 1;
|
||||
} else {
|
||||
x = 2;
|
||||
}
|
||||
if consteval {
|
||||
x = 3;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
struct ClassWithDestructor
|
||||
{
|
||||
ClassWithDestructor();
|
||||
ClassWithDestructor(const char*);
|
||||
~ClassWithDestructor();
|
||||
operator bool() const;
|
||||
};
|
||||
|
||||
bool destruction_on_consteval() {
|
||||
if consteval {
|
||||
return true;
|
||||
} else {
|
||||
ClassWithDestructor cwd;
|
||||
return cwd;
|
||||
}
|
||||
}
|
||||
|
||||
bool destruction_on_consteval2() {
|
||||
ClassWithDestructor cwd;
|
||||
if consteval {
|
||||
return true;
|
||||
} else {
|
||||
return cwd;
|
||||
}
|
||||
}
|
||||
@@ -24145,6 +24145,125 @@ ir.cpp:
|
||||
# 2725| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 2725| Type = [PlainCharType] char
|
||||
# 2725| ValueCategory = prvalue(load)
|
||||
ir23.cpp:
|
||||
# 1| [TopLevelFunction] bool consteval_1()
|
||||
# 1| <params>:
|
||||
# 2| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 3| getStmt(0): [ConstevalIfStmt] if consteval ...
|
||||
# 3| getThen(): [BlockStmt] { ... }
|
||||
# 4| getStmt(0): [ReturnStmt] return ...
|
||||
# 4| getExpr(): [Literal] 1
|
||||
# 4| Type = [BoolType] bool
|
||||
# 4| Value = [Literal] 1
|
||||
# 4| ValueCategory = prvalue
|
||||
# 5| getElse(): [BlockStmt] { ... }
|
||||
# 6| getStmt(0): [ReturnStmt] return ...
|
||||
# 6| getExpr(): [Literal] 0
|
||||
# 6| Type = [BoolType] bool
|
||||
# 6| Value = [Literal] 0
|
||||
# 6| ValueCategory = prvalue
|
||||
# 10| [TopLevelFunction] bool consteval_2()
|
||||
# 10| <params>:
|
||||
# 11| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 12| getStmt(0): [ConstevalIfStmt] if ! consteval ...
|
||||
# 12| getThen(): [BlockStmt] { ... }
|
||||
# 13| getStmt(0): [ReturnStmt] return ...
|
||||
# 13| getExpr(): [Literal] 1
|
||||
# 13| Type = [BoolType] bool
|
||||
# 13| Value = [Literal] 1
|
||||
# 13| ValueCategory = prvalue
|
||||
# 14| getElse(): [BlockStmt] { ... }
|
||||
# 15| getStmt(0): [ReturnStmt] return ...
|
||||
# 15| getExpr(): [Literal] 0
|
||||
# 15| Type = [BoolType] bool
|
||||
# 15| Value = [Literal] 0
|
||||
# 15| ValueCategory = prvalue
|
||||
# 19| [TopLevelFunction] bool consteval_3()
|
||||
# 19| <params>:
|
||||
# 20| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 21| getStmt(0): [ConstevalIfStmt] if consteval ...
|
||||
# 21| getThen(): [BlockStmt] { ... }
|
||||
# 22| getStmt(0): [ReturnStmt] return ...
|
||||
# 22| getExpr(): [Literal] 1
|
||||
# 22| Type = [BoolType] bool
|
||||
# 22| Value = [Literal] 1
|
||||
# 22| ValueCategory = prvalue
|
||||
# 25| getStmt(1): [ReturnStmt] return ...
|
||||
# 25| getExpr(): [Literal] 0
|
||||
# 25| Type = [BoolType] bool
|
||||
# 25| Value = [Literal] 0
|
||||
# 25| ValueCategory = prvalue
|
||||
# 28| [TopLevelFunction] bool consteval_4()
|
||||
# 28| <params>:
|
||||
# 29| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 30| getStmt(0): [ConstevalIfStmt] if ! consteval ...
|
||||
# 30| getThen(): [BlockStmt] { ... }
|
||||
# 31| getStmt(0): [ReturnStmt] return ...
|
||||
# 31| getExpr(): [Literal] 1
|
||||
# 31| Type = [BoolType] bool
|
||||
# 31| Value = [Literal] 1
|
||||
# 31| ValueCategory = prvalue
|
||||
# 34| getStmt(1): [ReturnStmt] return ...
|
||||
# 34| getExpr(): [Literal] 0
|
||||
# 34| Type = [BoolType] bool
|
||||
# 34| Value = [Literal] 0
|
||||
# 34| ValueCategory = prvalue
|
||||
# 37| [TopLevelFunction] bool consteval_5()
|
||||
# 37| <params>:
|
||||
# 38| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 39| getStmt(0): [DeclStmt] declaration
|
||||
# 39| getDeclarationEntry(0): [VariableDeclarationEntry] definition of r
|
||||
# 39| Type = [BoolType] bool
|
||||
# 39| getVariable().getInitializer(): [Initializer] initializer for r
|
||||
# 39| getExpr(): [Literal] 1
|
||||
# 39| Type = [BoolType] bool
|
||||
# 39| Value = [Literal] 1
|
||||
# 39| ValueCategory = prvalue
|
||||
# 41| getStmt(1): [ConstevalIfStmt] if ! consteval ...
|
||||
# 41| getThen(): [BlockStmt] { ... }
|
||||
# 42| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 42| getExpr(): [AssignExpr] ... = ...
|
||||
# 42| Type = [BoolType] bool
|
||||
# 42| ValueCategory = lvalue
|
||||
# 42| getLValue(): [VariableAccess] r
|
||||
# 42| Type = [BoolType] bool
|
||||
# 42| ValueCategory = lvalue
|
||||
# 42| getRValue(): [Literal] 0
|
||||
# 42| Type = [BoolType] bool
|
||||
# 42| Value = [Literal] 0
|
||||
# 42| ValueCategory = prvalue
|
||||
# 45| getStmt(2): [ReturnStmt] return ...
|
||||
# 45| getExpr(): [VariableAccess] r
|
||||
# 45| Type = [BoolType] bool
|
||||
# 45| ValueCategory = prvalue(load)
|
||||
# 48| [TopLevelFunction] bool consteval_6()
|
||||
# 48| <params>:
|
||||
# 49| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 50| getStmt(0): [DeclStmt] declaration
|
||||
# 50| getDeclarationEntry(0): [VariableDeclarationEntry] definition of r
|
||||
# 50| Type = [BoolType] bool
|
||||
# 50| getVariable().getInitializer(): [Initializer] initializer for r
|
||||
# 50| getExpr(): [Literal] 1
|
||||
# 50| Type = [BoolType] bool
|
||||
# 50| Value = [Literal] 1
|
||||
# 50| ValueCategory = prvalue
|
||||
# 52| getStmt(1): [ConstevalIfStmt] if consteval ...
|
||||
# 52| getThen(): [BlockStmt] { ... }
|
||||
# 53| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 53| getExpr(): [AssignExpr] ... = ...
|
||||
# 53| Type = [BoolType] bool
|
||||
# 53| ValueCategory = lvalue
|
||||
# 53| getLValue(): [VariableAccess] r
|
||||
# 53| Type = [BoolType] bool
|
||||
# 53| ValueCategory = lvalue
|
||||
# 53| getRValue(): [Literal] 0
|
||||
# 53| Type = [BoolType] bool
|
||||
# 53| Value = [Literal] 0
|
||||
# 53| ValueCategory = prvalue
|
||||
# 56| getStmt(2): [ReturnStmt] return ...
|
||||
# 56| getExpr(): [VariableAccess] r
|
||||
# 56| Type = [BoolType] bool
|
||||
# 56| ValueCategory = prvalue(load)
|
||||
many-defs-per-use.cpp:
|
||||
# 34| [TopLevelFunction] void many_defs_per_use()
|
||||
# 34| <params>:
|
||||
|
||||
@@ -19819,6 +19819,104 @@ ir.cpp:
|
||||
# 2724| v2724_12(void) = AliasedUse : ~m2725_8
|
||||
# 2724| v2724_13(void) = ExitFunction :
|
||||
|
||||
ir23.cpp:
|
||||
# 1| bool consteval_1()
|
||||
# 1| Block 0
|
||||
# 1| v1_1(void) = EnterFunction :
|
||||
# 1| m1_2(unknown) = AliasedDefinition :
|
||||
# 1| m1_3(unknown) = InitializeNonLocal :
|
||||
# 1| m1_4(unknown) = Chi : total:m1_2, partial:m1_3
|
||||
# 6| r6_1(glval<bool>) = VariableAddress[#return] :
|
||||
# 6| r6_2(bool) = Constant[0] :
|
||||
# 6| m6_3(bool) = Store[#return] : &:r6_1, r6_2
|
||||
# 1| r1_5(glval<bool>) = VariableAddress[#return] :
|
||||
# 1| v1_6(void) = ReturnValue : &:r1_5, m6_3
|
||||
# 1| v1_7(void) = AliasedUse : m1_3
|
||||
# 1| v1_8(void) = ExitFunction :
|
||||
|
||||
# 10| bool consteval_2()
|
||||
# 10| Block 0
|
||||
# 10| v10_1(void) = EnterFunction :
|
||||
# 10| m10_2(unknown) = AliasedDefinition :
|
||||
# 10| m10_3(unknown) = InitializeNonLocal :
|
||||
# 10| m10_4(unknown) = Chi : total:m10_2, partial:m10_3
|
||||
# 13| r13_1(glval<bool>) = VariableAddress[#return] :
|
||||
# 13| r13_2(bool) = Constant[1] :
|
||||
# 13| m13_3(bool) = Store[#return] : &:r13_1, r13_2
|
||||
# 10| r10_5(glval<bool>) = VariableAddress[#return] :
|
||||
# 10| v10_6(void) = ReturnValue : &:r10_5, m13_3
|
||||
# 10| v10_7(void) = AliasedUse : m10_3
|
||||
# 10| v10_8(void) = ExitFunction :
|
||||
|
||||
# 19| bool consteval_3()
|
||||
# 19| Block 0
|
||||
# 19| v19_1(void) = EnterFunction :
|
||||
# 19| m19_2(unknown) = AliasedDefinition :
|
||||
# 19| m19_3(unknown) = InitializeNonLocal :
|
||||
# 19| m19_4(unknown) = Chi : total:m19_2, partial:m19_3
|
||||
# 21| v21_1(void) = NoOp :
|
||||
# 25| r25_1(glval<bool>) = VariableAddress[#return] :
|
||||
# 25| r25_2(bool) = Constant[0] :
|
||||
# 25| m25_3(bool) = Store[#return] : &:r25_1, r25_2
|
||||
# 19| r19_5(glval<bool>) = VariableAddress[#return] :
|
||||
# 19| v19_6(void) = ReturnValue : &:r19_5, m25_3
|
||||
# 19| v19_7(void) = AliasedUse : m19_3
|
||||
# 19| v19_8(void) = ExitFunction :
|
||||
|
||||
# 28| bool consteval_4()
|
||||
# 28| Block 0
|
||||
# 28| v28_1(void) = EnterFunction :
|
||||
# 28| m28_2(unknown) = AliasedDefinition :
|
||||
# 28| m28_3(unknown) = InitializeNonLocal :
|
||||
# 28| m28_4(unknown) = Chi : total:m28_2, partial:m28_3
|
||||
# 31| r31_1(glval<bool>) = VariableAddress[#return] :
|
||||
# 31| r31_2(bool) = Constant[1] :
|
||||
# 31| m31_3(bool) = Store[#return] : &:r31_1, r31_2
|
||||
# 28| r28_5(glval<bool>) = VariableAddress[#return] :
|
||||
# 28| v28_6(void) = ReturnValue : &:r28_5, m31_3
|
||||
# 28| v28_7(void) = AliasedUse : m28_3
|
||||
# 28| v28_8(void) = ExitFunction :
|
||||
|
||||
# 37| bool consteval_5()
|
||||
# 37| Block 0
|
||||
# 37| v37_1(void) = EnterFunction :
|
||||
# 37| m37_2(unknown) = AliasedDefinition :
|
||||
# 37| m37_3(unknown) = InitializeNonLocal :
|
||||
# 37| m37_4(unknown) = Chi : total:m37_2, partial:m37_3
|
||||
# 39| r39_1(glval<bool>) = VariableAddress[r] :
|
||||
# 39| r39_2(bool) = Constant[1] :
|
||||
# 39| m39_3(bool) = Store[r] : &:r39_1, r39_2
|
||||
# 42| r42_1(bool) = Constant[0] :
|
||||
# 42| r42_2(glval<bool>) = VariableAddress[r] :
|
||||
# 42| m42_3(bool) = Store[r] : &:r42_2, r42_1
|
||||
# 45| r45_1(glval<bool>) = VariableAddress[#return] :
|
||||
# 45| r45_2(glval<bool>) = VariableAddress[r] :
|
||||
# 45| r45_3(bool) = Load[r] : &:r45_2, m42_3
|
||||
# 45| m45_4(bool) = Store[#return] : &:r45_1, r45_3
|
||||
# 37| r37_5(glval<bool>) = VariableAddress[#return] :
|
||||
# 37| v37_6(void) = ReturnValue : &:r37_5, m45_4
|
||||
# 37| v37_7(void) = AliasedUse : m37_3
|
||||
# 37| v37_8(void) = ExitFunction :
|
||||
|
||||
# 48| bool consteval_6()
|
||||
# 48| Block 0
|
||||
# 48| v48_1(void) = EnterFunction :
|
||||
# 48| m48_2(unknown) = AliasedDefinition :
|
||||
# 48| m48_3(unknown) = InitializeNonLocal :
|
||||
# 48| m48_4(unknown) = Chi : total:m48_2, partial:m48_3
|
||||
# 50| r50_1(glval<bool>) = VariableAddress[r] :
|
||||
# 50| r50_2(bool) = Constant[1] :
|
||||
# 50| m50_3(bool) = Store[r] : &:r50_1, r50_2
|
||||
# 52| v52_1(void) = NoOp :
|
||||
# 56| r56_1(glval<bool>) = VariableAddress[#return] :
|
||||
# 56| r56_2(glval<bool>) = VariableAddress[r] :
|
||||
# 56| r56_3(bool) = Load[r] : &:r56_2, m50_3
|
||||
# 56| m56_4(bool) = Store[#return] : &:r56_1, r56_3
|
||||
# 48| r48_5(glval<bool>) = VariableAddress[#return] :
|
||||
# 48| v48_6(void) = ReturnValue : &:r48_5, m56_4
|
||||
# 48| v48_7(void) = AliasedUse : m48_3
|
||||
# 48| v48_8(void) = ExitFunction :
|
||||
|
||||
many-defs-per-use.cpp:
|
||||
# 34| void many_defs_per_use()
|
||||
# 34| Block 0
|
||||
|
||||
59
cpp/ql/test/library-tests/ir/ir/ir23.cpp
Normal file
59
cpp/ql/test/library-tests/ir/ir/ir23.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
constexpr bool consteval_1() noexcept
|
||||
{
|
||||
if consteval {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr bool consteval_2() noexcept
|
||||
{
|
||||
if ! consteval {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr bool consteval_3() noexcept
|
||||
{
|
||||
if consteval {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr bool consteval_4() noexcept
|
||||
{
|
||||
if ! consteval {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr bool consteval_5() noexcept
|
||||
{
|
||||
bool r = true;
|
||||
|
||||
if ! consteval {
|
||||
r = false;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
constexpr bool consteval_6() noexcept
|
||||
{
|
||||
bool r = true;
|
||||
|
||||
if consteval {
|
||||
r = false;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// semmle-extractor-options: -std=c++23
|
||||
@@ -18132,6 +18132,143 @@ ir.cpp:
|
||||
# 2724| v2724_10(void) = AliasedUse : ~m?
|
||||
# 2724| v2724_11(void) = ExitFunction :
|
||||
|
||||
ir23.cpp:
|
||||
# 1| bool consteval_1()
|
||||
# 1| Block 0
|
||||
# 1| v1_1(void) = EnterFunction :
|
||||
# 1| mu1_2(unknown) = AliasedDefinition :
|
||||
# 1| mu1_3(unknown) = InitializeNonLocal :
|
||||
# 6| r6_1(glval<bool>) = VariableAddress[#return] :
|
||||
# 6| r6_2(bool) = Constant[0] :
|
||||
# 6| mu6_3(bool) = Store[#return] : &:r6_1, r6_2
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 1| Block 1
|
||||
# 1| r1_4(glval<bool>) = VariableAddress[#return] :
|
||||
# 1| v1_5(void) = ReturnValue : &:r1_4, ~m?
|
||||
# 1| v1_6(void) = AliasedUse : ~m?
|
||||
# 1| v1_7(void) = ExitFunction :
|
||||
|
||||
# 4| Block 2
|
||||
# 4| r4_1(glval<bool>) = VariableAddress[#return] :
|
||||
# 4| r4_2(bool) = Constant[1] :
|
||||
# 4| mu4_3(bool) = Store[#return] : &:r4_1, r4_2
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 10| bool consteval_2()
|
||||
# 10| Block 0
|
||||
# 10| v10_1(void) = EnterFunction :
|
||||
# 10| mu10_2(unknown) = AliasedDefinition :
|
||||
# 10| mu10_3(unknown) = InitializeNonLocal :
|
||||
# 13| r13_1(glval<bool>) = VariableAddress[#return] :
|
||||
# 13| r13_2(bool) = Constant[1] :
|
||||
# 13| mu13_3(bool) = Store[#return] : &:r13_1, r13_2
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 10| Block 1
|
||||
# 10| r10_4(glval<bool>) = VariableAddress[#return] :
|
||||
# 10| v10_5(void) = ReturnValue : &:r10_4, ~m?
|
||||
# 10| v10_6(void) = AliasedUse : ~m?
|
||||
# 10| v10_7(void) = ExitFunction :
|
||||
|
||||
# 15| Block 2
|
||||
# 15| r15_1(glval<bool>) = VariableAddress[#return] :
|
||||
# 15| r15_2(bool) = Constant[0] :
|
||||
# 15| mu15_3(bool) = Store[#return] : &:r15_1, r15_2
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 19| bool consteval_3()
|
||||
# 19| Block 0
|
||||
# 19| v19_1(void) = EnterFunction :
|
||||
# 19| mu19_2(unknown) = AliasedDefinition :
|
||||
# 19| mu19_3(unknown) = InitializeNonLocal :
|
||||
# 21| v21_1(void) = NoOp :
|
||||
# 25| r25_1(glval<bool>) = VariableAddress[#return] :
|
||||
# 25| r25_2(bool) = Constant[0] :
|
||||
# 25| mu25_3(bool) = Store[#return] : &:r25_1, r25_2
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 19| Block 1
|
||||
# 19| r19_4(glval<bool>) = VariableAddress[#return] :
|
||||
# 19| v19_5(void) = ReturnValue : &:r19_4, ~m?
|
||||
# 19| v19_6(void) = AliasedUse : ~m?
|
||||
# 19| v19_7(void) = ExitFunction :
|
||||
|
||||
# 22| Block 2
|
||||
# 22| r22_1(glval<bool>) = VariableAddress[#return] :
|
||||
# 22| r22_2(bool) = Constant[1] :
|
||||
# 22| mu22_3(bool) = Store[#return] : &:r22_1, r22_2
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 28| bool consteval_4()
|
||||
# 28| Block 0
|
||||
# 28| v28_1(void) = EnterFunction :
|
||||
# 28| mu28_2(unknown) = AliasedDefinition :
|
||||
# 28| mu28_3(unknown) = InitializeNonLocal :
|
||||
# 31| r31_1(glval<bool>) = VariableAddress[#return] :
|
||||
# 31| r31_2(bool) = Constant[1] :
|
||||
# 31| mu31_3(bool) = Store[#return] : &:r31_1, r31_2
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 28| Block 1
|
||||
# 28| r28_4(glval<bool>) = VariableAddress[#return] :
|
||||
# 28| v28_5(void) = ReturnValue : &:r28_4, ~m?
|
||||
# 28| v28_6(void) = AliasedUse : ~m?
|
||||
# 28| v28_7(void) = ExitFunction :
|
||||
|
||||
# 34| Block 2
|
||||
# 34| r34_1(glval<bool>) = VariableAddress[#return] :
|
||||
# 34| r34_2(bool) = Constant[0] :
|
||||
# 34| mu34_3(bool) = Store[#return] : &:r34_1, r34_2
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 37| bool consteval_5()
|
||||
# 37| Block 0
|
||||
# 37| v37_1(void) = EnterFunction :
|
||||
# 37| mu37_2(unknown) = AliasedDefinition :
|
||||
# 37| mu37_3(unknown) = InitializeNonLocal :
|
||||
# 39| r39_1(glval<bool>) = VariableAddress[r] :
|
||||
# 39| r39_2(bool) = Constant[1] :
|
||||
# 39| mu39_3(bool) = Store[r] : &:r39_1, r39_2
|
||||
# 42| r42_1(bool) = Constant[0] :
|
||||
# 42| r42_2(glval<bool>) = VariableAddress[r] :
|
||||
# 42| mu42_3(bool) = Store[r] : &:r42_2, r42_1
|
||||
# 45| r45_1(glval<bool>) = VariableAddress[#return] :
|
||||
# 45| r45_2(glval<bool>) = VariableAddress[r] :
|
||||
# 45| r45_3(bool) = Load[r] : &:r45_2, ~m?
|
||||
# 45| mu45_4(bool) = Store[#return] : &:r45_1, r45_3
|
||||
# 37| r37_4(glval<bool>) = VariableAddress[#return] :
|
||||
# 37| v37_5(void) = ReturnValue : &:r37_4, ~m?
|
||||
# 37| v37_6(void) = AliasedUse : ~m?
|
||||
# 37| v37_7(void) = ExitFunction :
|
||||
|
||||
# 48| bool consteval_6()
|
||||
# 48| Block 0
|
||||
# 48| v48_1(void) = EnterFunction :
|
||||
# 48| mu48_2(unknown) = AliasedDefinition :
|
||||
# 48| mu48_3(unknown) = InitializeNonLocal :
|
||||
# 50| r50_1(glval<bool>) = VariableAddress[r] :
|
||||
# 50| r50_2(bool) = Constant[1] :
|
||||
# 50| mu50_3(bool) = Store[r] : &:r50_1, r50_2
|
||||
# 52| v52_1(void) = NoOp :
|
||||
#-----| Goto -> Block 2
|
||||
|
||||
# 53| Block 1
|
||||
# 53| r53_1(bool) = Constant[0] :
|
||||
# 53| r53_2(glval<bool>) = VariableAddress[r] :
|
||||
# 53| mu53_3(bool) = Store[r] : &:r53_2, r53_1
|
||||
#-----| Goto -> Block 2
|
||||
|
||||
# 56| Block 2
|
||||
# 56| r56_1(glval<bool>) = VariableAddress[#return] :
|
||||
# 56| r56_2(glval<bool>) = VariableAddress[r] :
|
||||
# 56| r56_3(bool) = Load[r] : &:r56_2, ~m?
|
||||
# 56| mu56_4(bool) = Store[#return] : &:r56_1, r56_3
|
||||
# 48| r48_4(glval<bool>) = VariableAddress[#return] :
|
||||
# 48| v48_5(void) = ReturnValue : &:r48_4, ~m?
|
||||
# 48| v48_6(void) = AliasedUse : ~m?
|
||||
# 48| v48_7(void) = ExitFunction :
|
||||
|
||||
many-defs-per-use.cpp:
|
||||
# 34| void many_defs_per_use()
|
||||
# 34| Block 0
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#endif
|
||||
// semmle-extractor-options: -I${testdir}/more_headers/ "-U SOME_SYM"
|
||||
#undef BAR
|
||||
//#define SCARY(a,aa,aaah) /* we ignore a */ (aa /* but we take aa */) /* and we ignore aaa */
|
||||
#define SCARY(a,aa,aaah) /* we ignore a */ (aa /* but we take aa */) /* and we ignore aaa */
|
||||
#define LOG(fmt, ...) printf("Warning: %s", fmt, __VA__ARGS__)
|
||||
#include "pp.h"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
//#warning "This should happen"
|
||||
#warning "This should happen"
|
||||
#line 33 "emerald_city.h" // Magic!
|
||||
//#pragma byte_order(big_endian)
|
||||
#pragma byte_order(big_endian)
|
||||
#warning "Not in Kansas any more"
|
||||
|
||||
#define MULTILINE \
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 7 | 1 | 7 | 5 | PreprocessorElse | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 9 | 1 | 9 | 6 | PreprocessorEndif | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 11 | 1 | 11 | 10 | PreprocessorUndef | BAR | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 12 | 1 | 12 | 68 | Macro | SCARY(a,aa,aaah) | (aa ) |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 13 | 1 | 13 | 63 | Macro | LOG(fmt,__VA_ARGS__...) | printf("Warning: %s", fmt, __VA__ARGS__) |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 14 | 1 | 14 | 15 | Include | "pp.h" | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 16 | 1 | 16 | 5 | PreprocessorIf | 0 | N/A |
|
||||
@@ -32,7 +33,9 @@
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 76 | 1 | 76 | 20 | PreprocessorWarning | BAR defined | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 77 | 1 | 77 | 6 | PreprocessorEndif | N/A | N/A |
|
||||
| pp.h:0:0:0:0 | pp.h | 1 | 1 | 1 | 12 | PreprocessorPragma | once | N/A |
|
||||
| pp.h:0:0:0:0 | pp.h | 2 | 1 | 2 | 29 | PreprocessorWarning | "This should happen" | N/A |
|
||||
| pp.h:0:0:0:0 | pp.h | 3 | 1 | 3 | 27 | PreprocessorLine | 33 "emerald_city.h" | N/A |
|
||||
| pp.h:0:0:0:0 | pp.h | 4 | 1 | 4 | 30 | PreprocessorPragma | byte_order(big_endian) | N/A |
|
||||
| pp.h:0:0:0:0 | pp.h | 5 | 1 | 5 | 33 | PreprocessorWarning | "Not in Kansas any more" | N/A |
|
||||
| pp.h:0:0:0:0 | pp.h | 7 | 1 | 11 | 8 | Macro | MULTILINE | world a long |
|
||||
| pp.h:0:0:0:0 | pp.h | 13 | 1 | 14 | 11 | PreprocessorUndef | MULTILINE | N/A |
|
||||
|
||||
@@ -14,6 +14,7 @@ Microsoft.Android.Build,,1,14,,,,,,,,,,,,,1,,,,,,12,2
|
||||
Microsoft.Apple.Build,,,7,,,,,,,,,,,,,,,,,,,7,
|
||||
Microsoft.ApplicationBlocks.Data,28,,,,,,,,,,,,28,,,,,,,,,,
|
||||
Microsoft.AspNetCore.Components,2,4,2,,,,,,,2,,,,,,,,,4,,,1,1
|
||||
Microsoft.AspNetCore.Http,,,1,,,,,,,,,,,,,,,,,,,1,
|
||||
Microsoft.AspNetCore.Mvc,,,2,,,,,,,,,,,,,,,,,,,,2
|
||||
Microsoft.AspNetCore.WebUtilities,,,2,,,,,,,,,,,,,,,,,,,2,
|
||||
Microsoft.CSharp,,,2,,,,,,,,,,,,,,,,,,,2,
|
||||
|
||||
|
@@ -9,6 +9,6 @@ C# framework & library support
|
||||
Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting`
|
||||
`ServiceStack <https://servicestack.net/>`_,"``ServiceStack.*``, ``ServiceStack``",,7,194,
|
||||
System,"``System.*``, ``System``",47,10819,54,5
|
||||
Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``JsonToItemsTaskFactory``, ``Microsoft.Android.Build``, ``Microsoft.Apple.Build``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.AspNetCore.Components``, ``Microsoft.AspNetCore.Mvc``, ``Microsoft.AspNetCore.WebUtilities``, ``Microsoft.CSharp``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.DotNet.Build.Tasks``, ``Microsoft.DotNet.PlatformAbstractions``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.JSInterop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NET.Sdk.WebAssembly``, ``Microsoft.NET.WebAssembly.Webcil``, ``Microsoft.VisualBasic``, ``Microsoft.WebAssembly.Build.Tasks``, ``Microsoft.Win32``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",61,2074,152,4
|
||||
Totals,,108,12900,400,9
|
||||
Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``JsonToItemsTaskFactory``, ``Microsoft.Android.Build``, ``Microsoft.Apple.Build``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.AspNetCore.Components``, ``Microsoft.AspNetCore.Http``, ``Microsoft.AspNetCore.Mvc``, ``Microsoft.AspNetCore.WebUtilities``, ``Microsoft.CSharp``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.DotNet.Build.Tasks``, ``Microsoft.DotNet.PlatformAbstractions``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.JSInterop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NET.Sdk.WebAssembly``, ``Microsoft.NET.WebAssembly.Webcil``, ``Microsoft.VisualBasic``, ``Microsoft.WebAssembly.Build.Tasks``, ``Microsoft.Win32``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",61,2075,152,4
|
||||
Totals,,108,12901,400,9
|
||||
|
||||
|
||||
@@ -14,7 +14,12 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
/// </summary>
|
||||
private static IMethodSymbol? GetToStringMethod(ITypeSymbol? type)
|
||||
{
|
||||
return type?
|
||||
if (type is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var toString = type
|
||||
.GetMembers()
|
||||
.OfType<IMethodSymbol>()
|
||||
.Where(method =>
|
||||
@@ -22,6 +27,8 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
method.Parameters.Length == 0
|
||||
)
|
||||
.FirstOrDefault();
|
||||
|
||||
return toString ?? GetToStringMethod(type.BaseType);
|
||||
}
|
||||
|
||||
private ImplicitToString(ExpressionNodeInfo info, IMethodSymbol toString) : base(new ExpressionInfo(info.Context, AnnotatedTypeSymbol.CreateNotAnnotated(toString.ReturnType), info.Location, ExprKind.METHOD_INVOCATION, info.Parent, info.Child, isCompilerGenerated: true, info.ExprValue))
|
||||
|
||||
@@ -10,6 +10,10 @@ public class TestImplicitToString
|
||||
}
|
||||
}
|
||||
|
||||
public class Container2 : Container { }
|
||||
|
||||
public class Container3 { }
|
||||
|
||||
public class FormattableContainer : IFormattable
|
||||
{
|
||||
public string ToString(string format, IFormatProvider formatProvider)
|
||||
@@ -40,5 +44,11 @@ public class TestImplicitToString
|
||||
y = "Hello" + formattableContainer; // Implicit call to ToString().
|
||||
y = $"Hello {formattableContainer}"; // Implicit call to ToString(string, IFormatProvider). We don't handle this.
|
||||
y = $"Hello {formattableContainer:D}"; // Implicit call to ToString(string, IFormatProvider). We don't handle this.
|
||||
|
||||
var container2 = new Container2();
|
||||
y = "Hello" + container2; // Implicit Container.ToString call.
|
||||
|
||||
var container3 = new Container3();
|
||||
y = "Hello" + container3; // Implicit Object.ToString call.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
| implicitToString.cs:31:27:31:35 | call to method ToString |
|
||||
| implicitToString.cs:33:22:33:30 | call to method ToString |
|
||||
| implicitToString.cs:35:22:35:30 | call to method ToString |
|
||||
| implicitToString.cs:40:23:40:42 | call to method ToString |
|
||||
| implicitToString.cs:35:27:35:35 | call to method ToString | Container |
|
||||
| implicitToString.cs:37:22:37:30 | call to method ToString | Container |
|
||||
| implicitToString.cs:39:22:39:30 | call to method ToString | Container |
|
||||
| implicitToString.cs:44:23:44:42 | call to method ToString | FormattableContainer |
|
||||
| implicitToString.cs:49:23:49:32 | call to method ToString | Container |
|
||||
| implicitToString.cs:52:23:52:32 | call to method ToString | Object |
|
||||
|
||||
@@ -2,4 +2,4 @@ import csharp
|
||||
|
||||
from MethodCall c
|
||||
where c.isImplicit()
|
||||
select c
|
||||
select c, c.getTarget().getDeclaringType().toString()
|
||||
|
||||
@@ -908,8 +908,8 @@
|
||||
| D.cs:253:13:253:14 | access to local variable o2 | null | D.cs:249:18:249:38 | ... ? ... : ... | null |
|
||||
| D.cs:266:13:266:27 | ... is ... | true | D.cs:266:13:266:17 | access to local variable other | non-null |
|
||||
| D.cs:310:21:310:26 | ... + ... | non-null | D.cs:310:21:310:22 | "" | non-null |
|
||||
| D.cs:310:21:310:26 | ... + ... | non-null | D.cs:310:26:310:26 | access to parameter a | non-null |
|
||||
| D.cs:310:21:310:26 | ... + ... | null | D.cs:310:26:310:26 | access to parameter a | null |
|
||||
| D.cs:310:21:310:26 | ... + ... | non-null | D.cs:310:26:310:26 | call to method ToString | non-null |
|
||||
| D.cs:310:21:310:26 | ... + ... | null | D.cs:310:26:310:26 | call to method ToString | null |
|
||||
| D.cs:312:17:312:23 | !... | false | D.cs:312:18:312:23 | access to local variable s_null | true |
|
||||
| D.cs:312:17:312:23 | !... | true | D.cs:312:18:312:23 | access to local variable s_null | false |
|
||||
| D.cs:318:16:318:62 | ... && ... | true | D.cs:318:16:318:36 | ... == ... | true |
|
||||
|
||||
@@ -25,6 +25,8 @@ module BrokenCryptoAlgorithmConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,8 @@ module BuildArtifactLeakConfig implements DataFlow::ConfigSig {
|
||||
contents = DataFlow::ContentSet::anyProperty() and
|
||||
isSink(node)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,6 +41,8 @@ module CleartextLoggingConfig implements DataFlow::ConfigSig {
|
||||
contents = DataFlow::ContentSet::anyProperty() and
|
||||
isSink(node)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,6 +25,8 @@ module ClearTextStorageConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
module ClearTextStorageFlow = TaintTracking::Global<ClearTextStorageConfig>;
|
||||
|
||||
@@ -31,6 +31,8 @@ module ClientSideRequestForgeryConfig implements DataFlow::ConfigSig {
|
||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
isAdditionalRequestForgeryStep(node1, node2)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -54,6 +54,8 @@ module ClientSideUrlRedirectConfig implements DataFlow::StateConfigSig {
|
||||
state1 = state2
|
||||
)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,8 @@ module CodeInjectionConfig implements DataFlow::ConfigSig {
|
||||
// HTML sanitizers are insufficient protection against code injection
|
||||
node1 = node2.(HtmlSanitizerCall).getInput()
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,8 @@ module CommandInjectionConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) { isSinkWithHighlight(sink, _) }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,10 @@ module ConditionalBypassConfig implements DataFlow::ConfigSig {
|
||||
// comparing a tainted expression against a constant gives a tainted result
|
||||
node2.asExpr().(Comparison).hasOperands(node1.asExpr(), any(ConstantExpr c))
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() {
|
||||
none() // Disabled since the enclosing comparison is sometimes selected instead of the sink
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,6 +23,8 @@ module CorsMisconfigurationConfig implements DataFlow::ConfigSig {
|
||||
node instanceof Sanitizer or
|
||||
node = TaintTracking::AdHocWhitelistCheckSanitizer::getABarrierNode()
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,6 +33,8 @@ module DeepObjectResourceExhaustionConfig implements DataFlow::StateConfigSig {
|
||||
) {
|
||||
TaintedObject::isAdditionalFlowStep(node1, state1, node2, state2)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,10 @@ private module DifferentKindsComparisonBypassConfig implements DataFlow::ConfigS
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() {
|
||||
none() // Disabled since multiple related sinks are selected simultaneously
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -113,6 +113,8 @@ module DomBasedXssConfig implements DataFlow::StateConfigSig {
|
||||
state1 = state2
|
||||
)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -155,6 +155,8 @@ module ExceptionXssConfig implements DataFlow::StateConfigSig {
|
||||
}
|
||||
|
||||
int accessPathLimit() { result = 1 }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,6 +31,10 @@ module ExternalAPIUsedWithUntrustedDataConfig implements DataFlow::ConfigSig {
|
||||
// Also report values that escape while inside a property
|
||||
isSink(node) and contents = DataFlow::ContentSet::anyProperty()
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() {
|
||||
none() // Not used for PR analysis
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,8 @@ module FileAccessToHttpConfig implements DataFlow::ConfigSig {
|
||||
isSink(node) and
|
||||
contents = DataFlow::ContentSet::anyProperty()
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -69,6 +69,8 @@ module HardcodedCredentialsConfig implements DataFlow::ConfigSig {
|
||||
node2 = n.getACall()
|
||||
)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,6 +34,8 @@ module HardcodedDataInterpretedAsCodeConfig implements DataFlow::StateConfigSig
|
||||
state1 = [FlowState::modified(), FlowState::unmodified()] and
|
||||
state2 = FlowState::modified()
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,8 @@ module HostHeaderPoisoningConfig implements DataFlow::ConfigSig {
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node node) { exists(EmailSender email | node = email.getABody()) }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,8 @@ module HttpToFileAccessConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,8 @@ module ImproperCodeSanitizationConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,6 +42,8 @@ module IncompleteHtmlAttributeSanitizationConfig implements DataFlow::StateConfi
|
||||
}
|
||||
|
||||
predicate isBarrier(DataFlow::Node n) { n instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,6 +26,8 @@ module IndirectCommandInjectionConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) { isSinkWithHighlight(sink, _) }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,6 +23,8 @@ module InsecureDownloadConfig implements DataFlow::StateConfigSig {
|
||||
predicate isSink(DataFlow::Node sink, FlowState state) { sink.(Sink).getAFlowState() = state }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,6 +40,8 @@ module InsecureRandomnessConfig implements DataFlow::ConfigSig {
|
||||
// taint steps as additional flow steps.
|
||||
TaintTracking::defaultTaintStep(node1, node2)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,8 @@ module InsecureTemporaryFileConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,6 +25,8 @@ module InsufficientPasswordHashConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,8 @@ module LogInjectionConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,6 +38,8 @@ module LoopBoundInjectionConfig implements DataFlow::StateConfigSig {
|
||||
) {
|
||||
TaintedObject::isAdditionalFlowStep(node1, state1, node2, state2)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -51,6 +51,8 @@ module NosqlInjectionConfig implements DataFlow::StateConfigSig {
|
||||
state1.isTaint() and
|
||||
state2 = state1
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,6 +37,8 @@ module PostMessageStarConfig implements DataFlow::ConfigSig {
|
||||
// If an object leaks, all of its properties have leaked
|
||||
isSink(node) and contents = DataFlow::ContentSet::anyProperty()
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -113,6 +113,8 @@ module PrototypePollutingAssignmentConfig implements DataFlow::StateConfigSig {
|
||||
or
|
||||
node = DataFlow::MakeStateBarrierGuard<FlowState, BarrierGuard>::getABarrierNode(state)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/** Taint-tracking for reasoning about prototype-polluting assignments. */
|
||||
|
||||
@@ -47,6 +47,8 @@ module PrototypePollutionConfig implements DataFlow::StateConfigSig {
|
||||
predicate isBarrier(DataFlow::Node node, FlowState state) {
|
||||
node = TaintedObject::SanitizerGuard::getABarrierNode(state)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,6 +18,8 @@ module ReflectedXssConfig implements DataFlow::ConfigSig {
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
node instanceof Sanitizer or node = SharedXss::BarrierGuard::getABarrierNode()
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,8 @@ module RegExpInjectionConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,6 +23,8 @@ module RemotePropertyInjectionConfig implements DataFlow::ConfigSig {
|
||||
node instanceof Sanitizer or
|
||||
node = StringConcatenation::getRoot(any(ConstantString str).flow())
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,6 +26,8 @@ module RequestForgeryConfig implements DataFlow::ConfigSig {
|
||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
isAdditionalRequestForgeryStep(node1, node2)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,6 +27,8 @@ module ResourceExhaustionConfig implements DataFlow::ConfigSig {
|
||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
isNumericFlowStep(node1, node2)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -47,6 +47,8 @@ module SecondOrderCommandInjectionConfig implements DataFlow::StateConfigSig {
|
||||
TaintTracking::defaultTaintStep(node1, node2) and
|
||||
state1 = state2
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,8 @@ module ServerSideUrlRedirectConfig implements DataFlow::ConfigSig {
|
||||
node2 = call
|
||||
)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,6 +27,8 @@ module ShellCommandInjectionFromEnvironmentConfig implements DataFlow::ConfigSig
|
||||
predicate isSink(DataFlow::Node sink) { isSinkWithHighlight(sink, _) }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,6 +31,8 @@ module SqlInjectionConfig implements DataFlow::ConfigSig {
|
||||
node2 = call
|
||||
)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,8 @@ module StackTraceExposureConfig implements DataFlow::ConfigSig {
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node snk) { snk instanceof Sink }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,6 +18,8 @@ module StoredXssConfig implements DataFlow::ConfigSig {
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
node instanceof Sanitizer or node = Shared::BarrierGuard::getABarrierNode()
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,8 @@ module TaintedFormatStringConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -47,6 +47,8 @@ module TaintedPathConfig implements DataFlow::StateConfigSig {
|
||||
) {
|
||||
TaintedPath::isAdditionalFlowStep(node1, state1, node2, state2)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,6 +45,8 @@ module TemplateObjectInjectionConfig implements DataFlow::StateConfigSig {
|
||||
TaintTracking::defaultTaintStep(node1, node2) and
|
||||
state1 = state2
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,6 +27,8 @@ module TypeConfusionConfig implements DataFlow::ConfigSig {
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
node instanceof Barrier or node = DataFlow::MakeBarrierGuard<BarrierGuard>::getABarrierNode()
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,6 +32,8 @@ module UnsafeCodeConstruction {
|
||||
}
|
||||
|
||||
DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSourceCallContext }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,6 +18,8 @@ module UnsafeDeserializationConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -75,6 +75,8 @@ module UnsafeDynamicMethodAccessConfig implements DataFlow::StateConfigSig {
|
||||
TaintTracking::defaultTaintStep(node1, node2) and
|
||||
state1 = state2
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -60,6 +60,8 @@ module UnsafeHtmlConstructionConfig implements DataFlow::StateConfigSig {
|
||||
}
|
||||
|
||||
DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSourceCallContext }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,6 +36,8 @@ module UnsafeJQueryPluginConfig implements DataFlow::ConfigSig {
|
||||
// prefixing through a poor-mans templating system:
|
||||
node = any(StringReplaceCall call).getRawReplacement()
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,6 +25,8 @@ module UnsafeShellCommandConstructionConfig implements DataFlow::ConfigSig {
|
||||
}
|
||||
|
||||
DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSourceCallContext }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -91,6 +91,8 @@ module UnvalidatedDynamicMethodCallConfig implements DataFlow::StateConfigSig {
|
||||
TaintTracking::defaultTaintStep(node1, node2) and
|
||||
state1 = state2
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,8 @@ module XmlBombConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,8 @@ module XpathInjectionConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,8 @@ module XssThroughDomConfig implements DataFlow::ConfigSig {
|
||||
node2 = DataFlow::globalVarRef("URL").getAMemberCall("createObjectURL") and
|
||||
node1 = node2.(DataFlow::InvokeNode).getArgument(0)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,8 @@ module XxeConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -44,6 +44,8 @@ module ZipSlipConfig implements DataFlow::StateConfigSig {
|
||||
) {
|
||||
TaintedPath::isAdditionalFlowStep(node1, state1, node2, state2)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/** A taint tracking configuration for unsafe archive extraction. */
|
||||
|
||||
@@ -25,6 +25,8 @@ module PolynomialReDoSConfig implements DataFlow::ConfigSig {
|
||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
|
||||
|
||||
int fieldFlowBranchLimit() { result = 1 } // library inputs are too expensive on some projects
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/** Taint-tracking for reasoning about polynomial regular expression denial-of-service attacks. */
|
||||
|
||||
@@ -283,6 +283,10 @@ module PropNameTrackingConfig implements DataFlow::StateConfigSig {
|
||||
// flows through any contents, apart from a capture content.
|
||||
result = 1
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() {
|
||||
none() // Disabled since the alert references some locations other than the source or sink
|
||||
}
|
||||
}
|
||||
|
||||
class FlowState = PropNameTrackingConfig::FlowState;
|
||||
|
||||
@@ -87,6 +87,8 @@ module CodeInjectionConfig implements DataFlow::StateConfigSig {
|
||||
state1 = TTaint() and
|
||||
state2 = TUrlConstructor()
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
module CodeInjectionFlow = TaintTracking::GlobalWithState<CodeInjectionConfig>;
|
||||
|
||||
@@ -33,6 +33,8 @@ module EnvValueAndKeyInjectionConfig implements DataFlow::ConfigSig {
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
module EnvValueAndKeyInjectionFlow = TaintTracking::Global<EnvValueAndKeyInjectionConfig>;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user