Skip to content

Commit 10bf17c

Browse files
committed
Merge branch 'main' into polyQhelp
2 parents 480e71f + 58f4b76 commit 10bf17c

File tree

191 files changed

+4780
-3938
lines changed

Some content is hidden

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

191 files changed

+4780
-3938
lines changed

.github/workflows/check-change-note.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ jobs:
2727
run: |
2828
gh api 'repos/${{github.repository}}/pulls/${{github.event.number}}/files' --paginate --jq 'any(.[].filename ; test("/change-notes/.*[.]md$"))' |
2929
grep true -c
30-
- name: Fail if the change note filename doesn't match the expected format. The file name must be of the form 'YYYY-MM-DD.md' or 'YYYY-MM-DD-{title}.md', where '{title}' is arbitrary text.
30+
- name: Fail if the change note filename doesn't match the expected format. The file name must be of the form 'YYYY-MM-DD.md', 'YYYY-MM-DD-{title}.md', where '{title}' is arbitrary text, or released/x.y.z.md for released change-notes
3131
env:
3232
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3333
run: |
34-
gh api 'repos/${{github.repository}}/pulls/${{github.event.number}}/files' --paginate --jq '[.[].filename | select(test("/change-notes/.*[.]md$"))] | all(test("/change-notes/[0-9]{4}-[0-9]{2}-[0-9]{2}.*[.]md$"))' |
35-
grep true -c
34+
gh api 'repos/${{github.repository}}/pulls/${{github.event.number}}/files' --paginate --jq '[.[].filename | select(test("/change-notes/.*[.]md$"))] | all(test("/change-notes/[0-9]{4}-[0-9]{2}-[0-9]{2}.*[.]md$") or test("/change-notes/released/[0-9]*[.][0-9]*[.][0-9]*[.]md$"))' |
35+
grep true -c

.vscode/tasks.json

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,22 @@
2222
"command": "${config:python.pythonPath}",
2323
},
2424
"problemMatcher": []
25+
},
26+
{
27+
"label": "Accept .expected changes from CI",
28+
"type": "process",
29+
// Non-Windows OS will usually have Python 3 already installed at /usr/bin/python3.
30+
"command": "python3",
31+
"args": [
32+
"misc/scripts/accept-expected-changes-from-ci.py"
33+
],
34+
"group": "build",
35+
"windows": {
36+
// On Windows, use whatever Python interpreter is configured for this workspace. The default is
37+
// just `python`, so if Python is already on the path, this will find it.
38+
"command": "${config:python.pythonPath}",
39+
},
40+
"problemMatcher": []
2541
}
2642
]
27-
}
43+
}

CODEOWNERS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,6 @@ WORKSPACE.bazel @github/codeql-ci-reviewers
4040
/.github/workflows/ql-for-ql-* @github/codeql-ql-for-ql-reviewers
4141
/.github/workflows/ruby-* @github/codeql-ruby
4242
/.github/workflows/swift.yml @github/codeql-swift
43+
44+
# Misc
45+
/misc/scripts/accept-expected-changes-from-ci.py @RasmusWL

cpp/ql/lib/experimental/semmle/code/cpp/dataflow/ProductFlow.qll

Lines changed: 87 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,9 @@ module ProductFlow {
290290
predicate isBarrierIn(DataFlow::Node node) { Config::isBarrierIn1(node) }
291291
}
292292

293-
module Flow1 = DataFlow::GlobalWithState<Config1>;
293+
private module Flow1 = DataFlow::GlobalWithState<Config1>;
294294

295-
module Config2 implements DataFlow::StateConfigSig {
295+
private module Config2 implements DataFlow::StateConfigSig {
296296
class FlowState = FlowState2;
297297

298298
predicate isSource(DataFlow::Node source, FlowState state) {
@@ -322,27 +322,90 @@ module ProductFlow {
322322
predicate isBarrierIn(DataFlow::Node node) { Config::isBarrierIn2(node) }
323323
}
324324

325-
module Flow2 = DataFlow::GlobalWithState<Config2>;
325+
private module Flow2 = DataFlow::GlobalWithState<Config2>;
326326

327+
private predicate isSourcePair(Flow1::PathNode node1, Flow2::PathNode node2) {
328+
Config::isSourcePair(node1.getNode(), node1.getState(), node2.getNode(), node2.getState())
329+
}
330+
331+
private predicate isSinkPair(Flow1::PathNode node1, Flow2::PathNode node2) {
332+
Config::isSinkPair(node1.getNode(), node1.getState(), node2.getNode(), node2.getState())
333+
}
334+
335+
pragma[assume_small_delta]
327336
pragma[nomagic]
328-
private predicate reachableInterprocEntry(
329-
Flow1::PathNode source1, Flow2::PathNode source2, Flow1::PathNode node1, Flow2::PathNode node2
337+
private predicate fwdReachableInterprocEntry(Flow1::PathNode node1, Flow2::PathNode node2) {
338+
isSourcePair(node1, node2)
339+
or
340+
fwdIsSuccessor(_, _, node1, node2)
341+
}
342+
343+
pragma[nomagic]
344+
private predicate fwdIsSuccessorExit(
345+
Flow1::PathNode mid1, Flow2::PathNode mid2, Flow1::PathNode succ1, Flow2::PathNode succ2
330346
) {
331-
Config::isSourcePair(node1.getNode(), node1.getState(), node2.getNode(), node2.getState()) and
332-
node1 = source1 and
333-
node2 = source2
347+
isSinkPair(mid1, mid2) and
348+
succ1 = mid1 and
349+
succ2 = mid2
334350
or
335-
exists(
336-
Flow1::PathNode midEntry1, Flow2::PathNode midEntry2, Flow1::PathNode midExit1,
337-
Flow2::PathNode midExit2
338-
|
339-
reachableInterprocEntry(source1, source2, midEntry1, midEntry2) and
340-
interprocEdgePair(midExit1, midExit2, node1, node2) and
341-
localPathStep1*(midEntry1, midExit1) and
342-
localPathStep2*(midEntry2, midExit2)
351+
interprocEdgePair(mid1, mid2, succ1, succ2)
352+
}
353+
354+
private predicate fwdIsSuccessor1(
355+
Flow1::PathNode pred1, Flow2::PathNode pred2, Flow1::PathNode mid1, Flow2::PathNode mid2,
356+
Flow1::PathNode succ1, Flow2::PathNode succ2
357+
) {
358+
fwdReachableInterprocEntry(pred1, pred2) and
359+
localPathStep1*(pred1, mid1) and
360+
fwdIsSuccessorExit(pragma[only_bind_into](mid1), pragma[only_bind_into](mid2), succ1, succ2)
361+
}
362+
363+
private predicate fwdIsSuccessor2(
364+
Flow1::PathNode pred1, Flow2::PathNode pred2, Flow1::PathNode mid1, Flow2::PathNode mid2,
365+
Flow1::PathNode succ1, Flow2::PathNode succ2
366+
) {
367+
fwdReachableInterprocEntry(pred1, pred2) and
368+
localPathStep2*(pred2, mid2) and
369+
fwdIsSuccessorExit(pragma[only_bind_into](mid1), pragma[only_bind_into](mid2), succ1, succ2)
370+
}
371+
372+
pragma[assume_small_delta]
373+
private predicate fwdIsSuccessor(
374+
Flow1::PathNode pred1, Flow2::PathNode pred2, Flow1::PathNode succ1, Flow2::PathNode succ2
375+
) {
376+
exists(Flow1::PathNode mid1, Flow2::PathNode mid2 |
377+
fwdIsSuccessor1(pred1, pred2, mid1, mid2, succ1, succ2) and
378+
fwdIsSuccessor2(pred1, pred2, mid1, mid2, succ1, succ2)
379+
)
380+
}
381+
382+
pragma[assume_small_delta]
383+
pragma[nomagic]
384+
private predicate revReachableInterprocEntry(Flow1::PathNode node1, Flow2::PathNode node2) {
385+
fwdReachableInterprocEntry(node1, node2) and
386+
isSinkPair(node1, node2)
387+
or
388+
exists(Flow1::PathNode succ1, Flow2::PathNode succ2 |
389+
revReachableInterprocEntry(succ1, succ2) and
390+
fwdIsSuccessor(node1, node2, succ1, succ2)
343391
)
344392
}
345393

394+
private newtype TNodePair =
395+
TMkNodePair(Flow1::PathNode node1, Flow2::PathNode node2) {
396+
revReachableInterprocEntry(node1, node2)
397+
}
398+
399+
private predicate pathSucc(TNodePair n1, TNodePair n2) {
400+
exists(Flow1::PathNode n11, Flow2::PathNode n12, Flow1::PathNode n21, Flow2::PathNode n22 |
401+
n1 = TMkNodePair(n11, n12) and
402+
n2 = TMkNodePair(n21, n22) and
403+
fwdIsSuccessor(n11, n12, n21, n22)
404+
)
405+
}
406+
407+
private predicate pathSuccPlus(TNodePair n1, TNodePair n2) = fastTC(pathSucc/2)(n1, n2)
408+
346409
private predicate localPathStep1(Flow1::PathNode pred, Flow1::PathNode succ) {
347410
Flow1::PathGraph::edges(pred, succ) and
348411
pragma[only_bind_out](pred.getNode().getEnclosingCallable()) =
@@ -474,11 +537,14 @@ module ProductFlow {
474537
private predicate reachable(
475538
Flow1::PathNode source1, Flow2::PathNode source2, Flow1::PathNode sink1, Flow2::PathNode sink2
476539
) {
477-
exists(Flow1::PathNode mid1, Flow2::PathNode mid2 |
478-
reachableInterprocEntry(source1, source2, mid1, mid2) and
479-
Config::isSinkPair(sink1.getNode(), sink1.getState(), sink2.getNode(), sink2.getState()) and
480-
localPathStep1*(mid1, sink1) and
481-
localPathStep2*(mid2, sink2)
540+
isSourcePair(source1, source2) and
541+
isSinkPair(sink1, sink2) and
542+
exists(TNodePair n1, TNodePair n2 |
543+
n1 = TMkNodePair(source1, source2) and
544+
n2 = TMkNodePair(sink1, sink2)
545+
|
546+
pathSuccPlus(n1, n2) or
547+
n1 = n2
482548
)
483549
}
484550
}

cpp/ql/lib/semmle/code/cpp/Type.qll

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1699,7 +1699,28 @@ class AutoType extends TemplateParameter {
16991699

17001700
private predicate suppressUnusedThis(Type t) { any() }
17011701

1702-
/** A source code location referring to a type */
1702+
/**
1703+
* A source code location referring to a user-defined type.
1704+
*
1705+
* Note that only _user-defined_ types have `TypeMention`s. In particular,
1706+
* built-in types, and derived types with built-in types as their base don't
1707+
* have any `TypeMention`s. For example, given
1708+
* ```cpp
1709+
* struct S { ... };
1710+
* void f(S s1, int i1) {
1711+
* S s2;
1712+
* S* s3;
1713+
* S& s4 = s2;
1714+
* decltype(s2) s5;
1715+
*
1716+
* int i2;
1717+
* int* i3;
1718+
* int i4[10];
1719+
* }
1720+
* ```
1721+
* there will be a `TypeMention` for the mention of `S` at `S s1`, `S s2`, and `S& s4 = s2`,
1722+
* but not at `decltype(s2) s5`. Additionally, there will be no `TypeMention`s for `int`.
1723+
*/
17031724
class TypeMention extends Locatable, @type_mention {
17041725
override string toString() { result = "type mention" }
17051726

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

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -657,24 +657,16 @@ private predicate indirectConversionFlowStep(Node nFrom, Node nTo) {
657657
* So this predicate recurses back along conversions and `PointerArithmeticInstruction`s to find the
658658
* first use that has provides use-use flow, and uses that target as the target of the `nodeFrom`.
659659
*/
660-
private predicate adjustForPointerArith(
661-
DefOrUse defOrUse, Node nodeFrom, UseOrPhi use, boolean uncertain
662-
) {
663-
nodeFrom = any(PostUpdateNode pun).getPreUpdateNode() and
664-
exists(Node adjusted |
665-
indirectConversionFlowStep*(adjusted, nodeFrom) and
666-
nodeToDefOrUse(adjusted, defOrUse, uncertain) and
660+
private predicate adjustForPointerArith(PostUpdateNode pun, UseOrPhi use) {
661+
exists(DefOrUse defOrUse, Node adjusted |
662+
indirectConversionFlowStep*(adjusted, pun.getPreUpdateNode()) and
663+
nodeToDefOrUse(adjusted, defOrUse, _) and
667664
adjacentDefRead(defOrUse, use)
668665
)
669666
}
670667

671668
private predicate ssaFlowImpl(SsaDefOrUse defOrUse, Node nodeFrom, Node nodeTo, boolean uncertain) {
672-
// `nodeFrom = any(PostUpdateNode pun).getPreUpdateNode()` is implied by adjustedForPointerArith.
673669
exists(UseOrPhi use |
674-
adjustForPointerArith(defOrUse, nodeFrom, use, uncertain) and
675-
useToNode(use, nodeTo)
676-
or
677-
not nodeFrom = any(PostUpdateNode pun).getPreUpdateNode() and
678670
nodeToDefOrUse(nodeFrom, defOrUse, uncertain) and
679671
adjacentDefRead(defOrUse, use) and
680672
useToNode(use, nodeTo) and
@@ -719,14 +711,19 @@ predicate ssaFlow(Node nodeFrom, Node nodeTo) {
719711
)
720712
}
721713

714+
private predicate isArgumentOfCallable(DataFlowCall call, ArgumentNode arg) {
715+
arg.argumentOf(call, _)
716+
}
717+
718+
/** Holds if there is def-use or use-use flow from `pun` to `nodeTo`. */
722719
predicate postUpdateFlow(PostUpdateNode pun, Node nodeTo) {
723-
exists(Node preUpdate, Node nFrom, boolean uncertain, SsaDefOrUse defOrUse |
720+
exists(UseOrPhi use, Node preUpdate |
721+
adjustForPointerArith(pun, use) and
722+
useToNode(use, nodeTo) and
724723
preUpdate = pun.getPreUpdateNode() and
725-
ssaFlowImpl(defOrUse, nFrom, nodeTo, uncertain)
726-
|
727-
if uncertain = true
728-
then preUpdate = [nFrom, getAPriorDefinition(defOrUse)]
729-
else preUpdate = nFrom
724+
not exists(DataFlowCall call |
725+
isArgumentOfCallable(call, preUpdate) and isArgumentOfCallable(call, nodeTo)
726+
)
730727
)
731728
}
732729

0 commit comments

Comments
 (0)