Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9544b96

Browse files
committed
Merge branch 'main' into redsun82/swift-json
2 parents bd30335 + 3d0935a commit 9544b96

248 files changed

Lines changed: 3167 additions & 1940 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.devcontainer/devcontainer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"extensions": [
3-
"rust-lang.rust",
3+
"rust-lang.rust-analyzer",
44
"bungcip.better-toml",
55
"github.vscode-codeql",
66
"hbenl.vscode-test-explorer",
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Test tree-sitter-extractor
2+
3+
on:
4+
push:
5+
paths:
6+
- "shared/tree-sitter-extractor/**"
7+
- .github/workflows/tree-sitter-extractor-test.yml
8+
branches:
9+
- main
10+
- "rc/*"
11+
pull_request:
12+
paths:
13+
- "shared/tree-sitter-extractor/**"
14+
- .github/workflows/tree-sitter-extractor-test.yml
15+
branches:
16+
- main
17+
- "rc/*"
18+
19+
env:
20+
CARGO_TERM_COLOR: always
21+
22+
defaults:
23+
run:
24+
working-directory: shared/tree-sitter-extractor
25+
26+
jobs:
27+
test:
28+
steps:
29+
- uses: actions/checkout@v3
30+
- name: Check formatting
31+
run: cargo fmt --all -- --check
32+
- name: Run tests
33+
run: cargo test --verbose
34+
- name: Run clippy
35+
fmt:
36+
steps:
37+
- uses: actions/checkout@v3
38+
- name: Check formatting
39+
run: cargo fmt --check
40+
clippy:
41+
steps:
42+
- uses: actions/checkout@v3
43+
- name: Run clippy
44+
run: cargo clippy -- --no-deps -D warnings
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: feature
3+
---
4+
* A new predicate `BarrierGuard::getAnIndirectBarrierNode` has been added to the new dataflow library (`semmle.code.cpp.dataflow.new.DataFlow`) to mark indirect expressions as barrier nodes using the `BarrierGuard` API.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: majorAnalysis
3+
---
4+
* In the intermediate representation, handling of control flow after non-returning calls has been improved. This should remove false positives in queries that use the intermedite representation or libraries based on it, including the new data flow library.

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1903,7 +1903,38 @@ signature predicate guardChecksSig(IRGuardCondition g, Expr e, boolean branch);
19031903
* in data flow and taint tracking.
19041904
*/
19051905
module BarrierGuard<guardChecksSig/3 guardChecks> {
1906-
/** Gets a node that is safely guarded by the given guard check. */
1906+
/**
1907+
* Gets an expression node that is safely guarded by the given guard check.
1908+
*
1909+
* For example, given the following code:
1910+
* ```cpp
1911+
* int x = source();
1912+
* // ...
1913+
* if(is_safe_int(x)) {
1914+
* sink(x);
1915+
* }
1916+
* ```
1917+
* and the following barrier guard predicate:
1918+
* ```ql
1919+
* predicate myGuardChecks(IRGuardCondition g, Expr e, boolean branch) {
1920+
* exists(Call call |
1921+
* g.getUnconvertedResultExpression() = call and
1922+
* call.getTarget().hasName("is_safe_int") and
1923+
* e = call.getAnArgument() and
1924+
* branch = true
1925+
* )
1926+
* }
1927+
* ```
1928+
* implementing `isBarrier` as:
1929+
* ```ql
1930+
* predicate isBarrier(DataFlow::Node barrier) {
1931+
* barrier = DataFlow::BarrierGuard<myGuardChecks/3>::getABarrierNode()
1932+
* }
1933+
* ```
1934+
* will block flow from `x = source()` to `sink(x)`.
1935+
*
1936+
* NOTE: If an indirect expression is tracked, use `getAnIndirectBarrierNode` instead.
1937+
*/
19071938
ExprNode getABarrierNode() {
19081939
exists(IRGuardCondition g, Expr e, ValueNumber value, boolean edge |
19091940
e = value.getAnInstruction().getConvertedResultExpression() and
@@ -1912,6 +1943,84 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
19121943
g.controls(result.getBasicBlock(), edge)
19131944
)
19141945
}
1946+
1947+
/**
1948+
* Gets an indirect expression node that is safely guarded by the given guard check.
1949+
*
1950+
* For example, given the following code:
1951+
* ```cpp
1952+
* int* p;
1953+
* // ...
1954+
* *p = source();
1955+
* if(is_safe_pointer(p)) {
1956+
* sink(*p);
1957+
* }
1958+
* ```
1959+
* and the following barrier guard check:
1960+
* ```ql
1961+
* predicate myGuardChecks(IRGuardCondition g, Expr e, boolean branch) {
1962+
* exists(Call call |
1963+
* g.getUnconvertedResultExpression() = call and
1964+
* call.getTarget().hasName("is_safe_pointer") and
1965+
* e = call.getAnArgument() and
1966+
* branch = true
1967+
* )
1968+
* }
1969+
* ```
1970+
* implementing `isBarrier` as:
1971+
* ```ql
1972+
* predicate isBarrier(DataFlow::Node barrier) {
1973+
* barrier = DataFlow::BarrierGuard<myGuardChecks/3>::getAnIndirectBarrierNode()
1974+
* }
1975+
* ```
1976+
* will block flow from `x = source()` to `sink(x)`.
1977+
*
1978+
* NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
1979+
*/
1980+
IndirectExprNode getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) }
1981+
1982+
/**
1983+
* Gets an indirect expression node with indirection index `indirectionIndex` that is
1984+
* safely guarded by the given guard check.
1985+
*
1986+
* For example, given the following code:
1987+
* ```cpp
1988+
* int* p;
1989+
* // ...
1990+
* *p = source();
1991+
* if(is_safe_pointer(p)) {
1992+
* sink(*p);
1993+
* }
1994+
* ```
1995+
* and the following barrier guard check:
1996+
* ```ql
1997+
* predicate myGuardChecks(IRGuardCondition g, Expr e, boolean branch) {
1998+
* exists(Call call |
1999+
* g.getUnconvertedResultExpression() = call and
2000+
* call.getTarget().hasName("is_safe_pointer") and
2001+
* e = call.getAnArgument() and
2002+
* branch = true
2003+
* )
2004+
* }
2005+
* ```
2006+
* implementing `isBarrier` as:
2007+
* ```ql
2008+
* predicate isBarrier(DataFlow::Node barrier) {
2009+
* barrier = DataFlow::BarrierGuard<myGuardChecks/3>::getAnIndirectBarrierNode(1)
2010+
* }
2011+
* ```
2012+
* will block flow from `x = source()` to `sink(x)`.
2013+
*
2014+
* NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
2015+
*/
2016+
IndirectExprNode getAnIndirectBarrierNode(int indirectionIndex) {
2017+
exists(IRGuardCondition g, Expr e, ValueNumber value, boolean edge |
2018+
e = value.getAnInstruction().getConvertedResultExpression() and
2019+
result.getConvertedExpr(indirectionIndex) = e and
2020+
guardChecks(g, value.getAnInstruction().getConvertedResultExpression(), edge) and
2021+
g.controls(result.getBasicBlock(), edge)
2022+
)
2023+
}
19152024
}
19162025

19172026
/**

cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,13 @@ private module Cached {
3434

3535
cached
3636
predicate hasUnreachedInstructionCached(IRFunction irFunc) {
37-
exists(OldInstruction oldInstruction |
37+
exists(OldIR::Instruction oldInstruction |
3838
irFunc = oldInstruction.getEnclosingIRFunction() and
39-
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _)
39+
(
40+
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _)
41+
or
42+
oldInstruction.getOpcode() instanceof Opcode::Unreached
43+
)
4044
)
4145
}
4246

@@ -366,21 +370,19 @@ private module Cached {
366370
then
367371
result = getChi(getOldInstruction(instruction)) and
368372
kind instanceof GotoEdge
369-
else (
373+
else
370374
exists(OldInstruction oldInstruction |
371-
oldInstruction = getOldInstruction(instruction) and
375+
(
376+
oldInstruction = getOldInstruction(instruction)
377+
or
378+
instruction = getChi(oldInstruction)
379+
) and
372380
(
373381
if Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind)
374382
then result = unreachedInstruction(instruction.getEnclosingIRFunction())
375383
else result = getNewInstruction(oldInstruction.getSuccessor(kind))
376384
)
377385
)
378-
or
379-
exists(OldInstruction oldInstruction |
380-
instruction = getChi(oldInstruction) and
381-
result = getNewInstruction(oldInstruction.getSuccessor(kind))
382-
)
383-
)
384386
}
385387

386388
cached

cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstruction.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ newtype TInstruction =
1919
) {
2020
IRConstruction::Raw::hasInstruction(tag1, tag2)
2121
} or
22+
TRawUnreachedInstruction(IRFunctionBase irFunc) {
23+
IRConstruction::hasUnreachedInstruction(irFunc)
24+
} or
2225
TUnaliasedSsaPhiInstruction(
2326
TRawInstruction blockStartInstr, UnaliasedSsa::Ssa::MemoryLocation memoryLocation
2427
) {

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,9 @@ module Raw {
178178
}
179179
}
180180

181-
class TStageInstruction = TRawInstruction;
181+
class TStageInstruction = TRawInstruction or TRawUnreachedInstruction;
182182

183-
predicate hasInstruction(TRawInstruction instr) { any() }
183+
predicate hasInstruction(TStageInstruction instr) { any() }
184184

185185
predicate hasModeledMemoryResult(Instruction instruction) { none() }
186186

@@ -368,6 +368,11 @@ private predicate isStrictlyForwardGoto(GotoStmt goto) {
368368

369369
Locatable getInstructionAst(TStageInstruction instr) {
370370
result = getInstructionTranslatedElement(instr).getAst()
371+
or
372+
exists(IRFunction irFunc |
373+
instr = TRawUnreachedInstruction(irFunc) and
374+
result = irFunc.getFunction()
375+
)
371376
}
372377

373378
/** DEPRECATED: Alias for getInstructionAst */
@@ -377,14 +382,22 @@ deprecated Locatable getInstructionAST(TStageInstruction instr) {
377382

378383
CppType getInstructionResultType(TStageInstruction instr) {
379384
getInstructionTranslatedElement(instr).hasInstruction(_, getInstructionTag(instr), result)
385+
or
386+
instr instanceof TRawUnreachedInstruction and
387+
result = getVoidType()
380388
}
381389

382390
predicate getInstructionOpcode(Opcode opcode, TStageInstruction instr) {
383391
getInstructionTranslatedElement(instr).hasInstruction(opcode, getInstructionTag(instr), _)
392+
or
393+
instr instanceof TRawUnreachedInstruction and
394+
opcode instanceof Opcode::Unreached
384395
}
385396

386397
IRFunctionBase getInstructionEnclosingIRFunction(TStageInstruction instr) {
387398
result.getFunction() = getInstructionTranslatedElement(instr).getFunction()
399+
or
400+
instr = TRawUnreachedInstruction(result)
388401
}
389402

390403
Instruction getPrimaryInstructionForSideEffect(SideEffectInstruction instruction) {
@@ -393,6 +406,16 @@ Instruction getPrimaryInstructionForSideEffect(SideEffectInstruction instruction
393406
.getPrimaryInstructionForSideEffect(getInstructionTag(instruction))
394407
}
395408

409+
predicate hasUnreachedInstruction(IRFunction func) {
410+
exists(Call c |
411+
c.getEnclosingFunction() = func.getFunction() and
412+
any(Options opt).exits(c.getTarget())
413+
) and
414+
not exists(TranslatedUnreachableReturnStmt return |
415+
return.getEnclosingFunction().getFunction() = func.getFunction()
416+
)
417+
}
418+
396419
import CachedForDebugging
397420

398421
cached

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ newtype TInstructionTag =
3434
CallTargetTag() or
3535
CallTag() or
3636
CallSideEffectTag() or
37+
CallNoReturnTag() or
3738
AllocationSizeTag() or
3839
AllocationElementSizeTag() or
3940
AllocationExtentConvertTag() or

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ private import SideEffects
88
private import TranslatedElement
99
private import TranslatedExpr
1010
private import TranslatedFunction
11+
private import DefaultOptions as DefaultOptions
1112

1213
/**
1314
* Gets the `CallInstruction` from the `TranslatedCallExpr` for the specified expression.
@@ -66,7 +67,13 @@ abstract class TranslatedCall extends TranslatedExpr {
6667
)
6768
or
6869
child = getSideEffects() and
69-
result = getParent().getChildSuccessor(this)
70+
if this.isNoReturn()
71+
then
72+
result =
73+
any(UnreachedInstruction instr |
74+
this.getEnclosingFunction().getFunction() = instr.getEnclosingFunction()
75+
)
76+
else result = this.getParent().getChildSuccessor(this)
7077
}
7178

7279
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
@@ -161,6 +168,8 @@ abstract class TranslatedCall extends TranslatedExpr {
161168
*/
162169
abstract predicate hasArguments();
163170

171+
predicate isNoReturn() { none() }
172+
164173
final TranslatedSideEffects getSideEffects() { result.getExpr() = expr }
165174
}
166175

@@ -266,6 +275,8 @@ abstract class TranslatedCallExpr extends TranslatedNonConstantExpr, TranslatedC
266275
}
267276

268277
final override int getNumberOfArguments() { result = expr.getNumberOfArguments() }
278+
279+
final override predicate isNoReturn() { any(Options opt).exits(expr.getTarget()) }
269280
}
270281

271282
/**

0 commit comments

Comments
 (0)