Skip to content

Commit 7e23ccd

Browse files
committed
Merge branch 'main' into rdmarsh2/cpp/ir-synthetic-destructors
2 parents 128bc99 + 7217dfa commit 7e23ccd

File tree

762 files changed

+46828
-45026
lines changed

Some content is hidden

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

762 files changed

+46828
-45026
lines changed

.github/workflows/qhelp-pr-preview.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ jobs:
7777
done < "${RUNNER_TEMP}/paths.txt" >> comment_body.txt
7878
exit "${EXIT_CODE}"
7979
80-
- if: always()
80+
- if: ${{ !cancelled() }}
8181
uses: actions/upload-artifact@v3
8282
with:
8383
name: comment

cpp/ql/lib/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## 0.12.5
2+
3+
### New Features
4+
5+
* Added the `PreprocBlock.qll` library to this repository. This library offers a view of `#if`, `#elif`, `#else` and similar directives as a tree with navigable parent-child relationships.
6+
* Added a new `ThrowingFunction` abstract class that can be used to model an external function that may throw an exception.
7+
18
## 0.12.4
29

310
### Minor Analysis Improvements

cpp/ql/lib/change-notes/2024-01-30-throwing-model.md

Lines changed: 0 additions & 4 deletions
This file was deleted.

cpp/ql/lib/change-notes/2024-02-06-flow-out-barrier-function.md

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
---
2-
category: feature
3-
---
1+
## 0.12.5
2+
3+
### New Features
4+
45
* Added the `PreprocBlock.qll` library to this repository. This library offers a view of `#if`, `#elif`, `#else` and similar directives as a tree with navigable parent-child relationships.
6+
* Added a new `ThrowingFunction` abstract class that can be used to model an external function that may throw an exception.

cpp/ql/lib/codeql-pack.release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
lastReleaseVersion: 0.12.4
2+
lastReleaseVersion: 0.12.5

cpp/ql/lib/qlpack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: codeql/cpp-all
2-
version: 0.12.5-dev
2+
version: 0.12.6-dev
33
groups: cpp
44
dbscheme: semmlecode.cpp.dbscheme
55
extractor: cpp

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

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ class FinalGlobalValue extends Node, TFinalGlobalValue {
709709
override DataFlowType getType() {
710710
exists(int indirectionIndex |
711711
indirectionIndex = globalUse.getIndirectionIndex() and
712-
result = getTypeImpl(globalUse.getUnspecifiedType(), indirectionIndex - 1)
712+
result = getTypeImpl(globalUse.getUnderlyingType(), indirectionIndex - 1)
713713
)
714714
}
715715

@@ -740,7 +740,7 @@ class InitialGlobalValue extends Node, TInitialGlobalValue {
740740

741741
override DataFlowType getType() {
742742
exists(DataFlowType type |
743-
type = globalDef.getUnspecifiedType() and
743+
type = globalDef.getUnderlyingType() and
744744
if this.isGLValue()
745745
then result = type
746746
else result = getTypeImpl(type, globalDef.getIndirectionIndex() - 1)
@@ -943,10 +943,13 @@ private Type getTypeImpl0(Type t, int indirectionIndex) {
943943
indirectionIndex > 0 and
944944
exists(Type stripped |
945945
stripped = stripPointer(t.stripTopLevelSpecifiers()) and
946-
// We need to avoid the case where `stripPointer(t) = t` (which can happen on
947-
// iterators that specify a `value_type` that is the iterator itself). Such a type
948-
// would create an infinite loop otherwise. For these cases we simply don't produce
949-
// a result for `getTypeImpl`.
946+
// We need to avoid the case where `stripPointer(t) = t` (which can happen
947+
// on iterators that specify a `value_type` that is the iterator itself).
948+
// Such a type would create an infinite loop otherwise. For these cases we
949+
// simply don't produce a result for `getTypeImpl`.
950+
// To be on the safe side, we check whether the _unspecified_ type has
951+
// changed since this also prevents an infinite loop when `stripped` and
952+
// `t` only differ by const'ness or volatile'ness.
950953
stripped.getUnspecifiedType() != t.getUnspecifiedType() and
951954
result = getTypeImpl0(stripped, indirectionIndex - 1)
952955
)
@@ -996,12 +999,14 @@ private module RawIndirectNodes {
996999

9971000
override Declaration getEnclosingCallable() { result = this.getFunction() }
9981001

1002+
override predicate isGLValue() { this.getOperand().isGLValue() }
1003+
9991004
override DataFlowType getType() {
10001005
exists(int sub, DataFlowType type, boolean isGLValue |
10011006
type = getOperandType(this.getOperand(), isGLValue) and
10021007
if isGLValue = true then sub = 1 else sub = 0
10031008
|
1004-
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
1009+
result = getTypeImpl(type.getUnderlyingType(), indirectionIndex - sub)
10051010
)
10061011
}
10071012

@@ -1038,12 +1043,14 @@ private module RawIndirectNodes {
10381043

10391044
override Declaration getEnclosingCallable() { result = this.getFunction() }
10401045

1046+
override predicate isGLValue() { this.getInstruction().isGLValue() }
1047+
10411048
override DataFlowType getType() {
10421049
exists(int sub, DataFlowType type, boolean isGLValue |
10431050
type = getInstructionType(this.getInstruction(), isGLValue) and
10441051
if isGLValue = true then sub = 1 else sub = 0
10451052
|
1046-
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
1053+
result = getTypeImpl(type.getUnderlyingType(), indirectionIndex - sub)
10471054
)
10481055
}
10491056

@@ -1136,7 +1143,7 @@ class FinalParameterNode extends Node, TFinalParameterNode {
11361143

11371144
override Declaration getEnclosingCallable() { result = this.getFunction() }
11381145

1139-
override DataFlowType getType() { result = getTypeImpl(p.getUnspecifiedType(), indirectionIndex) }
1146+
override DataFlowType getType() { result = getTypeImpl(p.getUnderlyingType(), indirectionIndex) }
11401147

11411148
final override Location getLocationImpl() {
11421149
// Parameters can have multiple locations. When there's a unique location we use
@@ -1789,7 +1796,7 @@ class VariableNode extends Node, TVariableNode {
17891796
}
17901797

17911798
override DataFlowType getType() {
1792-
result = getTypeImpl(v.getUnspecifiedType(), indirectionIndex - 1)
1799+
result = getTypeImpl(v.getUnderlyingType(), indirectionIndex - 1)
17931800
}
17941801

17951802
final override Location getLocationImpl() {

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -507,13 +507,13 @@ module ProductFlow {
507507
private predicate pathSuccPlus(TNodePair n1, TNodePair n2) = fastTC(pathSucc/2)(n1, n2)
508508

509509
private predicate localPathStep1(Flow1::PathNode pred, Flow1::PathNode succ) {
510-
Flow1::PathGraph::edges(pred, succ) and
510+
Flow1::PathGraph::edges(pred, succ, _, _) and
511511
pragma[only_bind_out](pred.getNode().getEnclosingCallable()) =
512512
pragma[only_bind_out](succ.getNode().getEnclosingCallable())
513513
}
514514

515515
private predicate localPathStep2(Flow2::PathNode pred, Flow2::PathNode succ) {
516-
Flow2::PathGraph::edges(pred, succ) and
516+
Flow2::PathGraph::edges(pred, succ, _, _) and
517517
pragma[only_bind_out](pred.getNode().getEnclosingCallable()) =
518518
pragma[only_bind_out](succ.getNode().getEnclosingCallable())
519519
}
@@ -530,7 +530,7 @@ module ProductFlow {
530530
TJump()
531531

532532
private predicate intoImpl1(Flow1::PathNode pred1, Flow1::PathNode succ1, DataFlowCall call) {
533-
Flow1::PathGraph::edges(pred1, succ1) and
533+
Flow1::PathGraph::edges(pred1, succ1, _, _) and
534534
pred1.getNode().(ArgumentNode).getCall() = call and
535535
succ1.getNode() instanceof ParameterNode
536536
}
@@ -543,7 +543,7 @@ module ProductFlow {
543543
}
544544

545545
private predicate outImpl1(Flow1::PathNode pred1, Flow1::PathNode succ1, DataFlowCall call) {
546-
Flow1::PathGraph::edges(pred1, succ1) and
546+
Flow1::PathGraph::edges(pred1, succ1, _, _) and
547547
exists(ReturnKindExt returnKind |
548548
succ1.getNode() = returnKind.getAnOutNode(call) and
549549
pred1.getNode().(ReturnNodeExt).getKind() = returnKind
@@ -558,7 +558,7 @@ module ProductFlow {
558558
}
559559

560560
private predicate intoImpl2(Flow2::PathNode pred2, Flow2::PathNode succ2, DataFlowCall call) {
561-
Flow2::PathGraph::edges(pred2, succ2) and
561+
Flow2::PathGraph::edges(pred2, succ2, _, _) and
562562
pred2.getNode().(ArgumentNode).getCall() = call and
563563
succ2.getNode() instanceof ParameterNode
564564
}
@@ -571,7 +571,7 @@ module ProductFlow {
571571
}
572572

573573
private predicate outImpl2(Flow2::PathNode pred2, Flow2::PathNode succ2, DataFlowCall call) {
574-
Flow2::PathGraph::edges(pred2, succ2) and
574+
Flow2::PathGraph::edges(pred2, succ2, _, _) and
575575
exists(ReturnKindExt returnKind |
576576
succ2.getNode() = returnKind.getAnOutNode(call) and
577577
pred2.getNode().(ReturnNodeExt).getKind() = returnKind
@@ -590,7 +590,7 @@ module ProductFlow {
590590
Declaration predDecl, Declaration succDecl, Flow1::PathNode pred1, Flow1::PathNode succ1,
591591
TKind kind
592592
) {
593-
Flow1::PathGraph::edges(pred1, succ1) and
593+
Flow1::PathGraph::edges(pred1, succ1, _, _) and
594594
predDecl != succDecl and
595595
pred1.getNode().getEnclosingCallable() = predDecl and
596596
succ1.getNode().getEnclosingCallable() = succDecl and
@@ -610,7 +610,7 @@ module ProductFlow {
610610
Declaration predDecl, Declaration succDecl, Flow2::PathNode pred2, Flow2::PathNode succ2,
611611
TKind kind
612612
) {
613-
Flow2::PathGraph::edges(pred2, succ2) and
613+
Flow2::PathGraph::edges(pred2, succ2, _, _) and
614614
predDecl != succDecl and
615615
pred2.getNode().getEnclosingCallable() = predDecl and
616616
succ2.getNode().getEnclosingCallable() = succDecl and

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

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,8 @@ private import codeql.ssa.Ssa as SsaImplCommon
22
private import semmle.code.cpp.ir.IR
33
private import DataFlowUtil
44
private import DataFlowImplCommon as DataFlowImplCommon
5-
private import semmle.code.cpp.ir.dataflow.internal.ModelUtil
65
private import semmle.code.cpp.models.interfaces.Allocation as Alloc
76
private import semmle.code.cpp.models.interfaces.DataFlow as DataFlow
8-
private import semmle.code.cpp.models.interfaces.FlowOutBarrier as FOB
9-
private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs as FIO
107
private import semmle.code.cpp.ir.internal.IRCppLanguage
118
private import DataFlowPrivate
129
private import ssa0.SsaInternals as SsaInternals0
@@ -548,6 +545,11 @@ class GlobalUse extends UseImpl, TGlobalUse {
548545
*/
549546
Type getUnspecifiedType() { result = global.getUnspecifiedType() }
550547

548+
/**
549+
* Gets the type of this use, after typedefs have been resolved.
550+
*/
551+
Type getUnderlyingType() { result = global.getUnderlyingType() }
552+
551553
override predicate isCertain() { any() }
552554

553555
override BaseSourceVariableInstruction getBase() { none() }
@@ -591,11 +593,16 @@ class GlobalDefImpl extends DefOrUseImpl, TGlobalDefImpl {
591593
int getIndirection() { result = indirectionIndex }
592594

593595
/**
594-
* Gets the type of this use after specifiers have been deeply stripped
595-
* and typedefs have been resolved.
596+
* Gets the type of this definition after specifiers have been deeply
597+
* stripped and typedefs have been resolved.
596598
*/
597599
Type getUnspecifiedType() { result = global.getUnspecifiedType() }
598600

601+
/**
602+
* Gets the type of this definition, after typedefs have been resolved.
603+
*/
604+
Type getUnderlyingType() { result = global.getUnderlyingType() }
605+
599606
override string toString() { result = "Def of " + this.getSourceVariable() }
600607

601608
override Location getLocation() { result = f.getLocation() }
@@ -787,30 +794,10 @@ private Node getAPriorDefinition(SsaDefOrUse defOrUse) {
787794
)
788795
}
789796

790-
/**
791-
* Holds if there should not be use-use flow out of `n` (or a conversion that
792-
* flows to `n`).
793-
*/
794-
private predicate modeledFlowBarrier(Node n) {
795-
exists(FIO::FunctionInput input, CallInstruction call |
796-
call.getStaticCallTarget().(FOB::FlowOutBarrierFunction).isFlowOutBarrier(input) and
797-
n = callInput(call, input)
798-
)
799-
or
800-
exists(Operand operand, Instruction instr, Node n0, int indirectionIndex |
801-
modeledFlowBarrier(n0) and
802-
nodeHasInstruction(n0, instr, indirectionIndex) and
803-
conversionFlow(operand, instr, false, _) and
804-
nodeHasOperand(n, operand, indirectionIndex)
805-
)
806-
}
807-
808797
/** Holds if there is def-use or use-use flow from `nodeFrom` to `nodeTo`. */
809798
predicate ssaFlow(Node nodeFrom, Node nodeTo) {
810799
exists(Node nFrom, boolean uncertain, SsaDefOrUse defOrUse |
811-
ssaFlowImpl(defOrUse, nFrom, nodeTo, uncertain) and
812-
not modeledFlowBarrier(nFrom) and
813-
nodeFrom != nodeTo
800+
ssaFlowImpl(defOrUse, nFrom, nodeTo, uncertain) and nodeFrom != nodeTo
814801
|
815802
if uncertain = true then nodeFrom = [nFrom, getAPriorDefinition(defOrUse)] else nodeFrom = nFrom
816803
)
@@ -1115,6 +1102,11 @@ class GlobalDef extends TGlobalDef, SsaDefOrUse {
11151102
*/
11161103
DataFlowType getUnspecifiedType() { result = global.getUnspecifiedType() }
11171104

1105+
/**
1106+
* Gets the type of this definition, after typedefs have been resolved.
1107+
*/
1108+
DataFlowType getUnderlyingType() { result = global.getUnderlyingType() }
1109+
11181110
/** Gets the `IRFunction` whose body is evaluated after this definition. */
11191111
IRFunction getIRFunction() { result = global.getIRFunction() }
11201112

0 commit comments

Comments
 (0)