Skip to content

Commit fe35902

Browse files
committed
Merge branch 'main' into redsun82/kotlin
2 parents 24ef424 + 3c12863 commit fe35902

File tree

164 files changed

+4938
-16826
lines changed

Some content is hidden

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

164 files changed

+4938
-16826
lines changed

MODULE.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ pip.parse(
3232
use_repo(pip, "codegen_deps")
3333

3434
swift_deps = use_extension("//swift/third_party:load.bzl", "swift_deps")
35+
36+
# following list can be kept in sync with `bazel mod tidy`
3537
use_repo(
3638
swift_deps,
3739
"binlog",

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -506,8 +506,7 @@ private module IRDeclarationEntries {
506506
* An entity that represents a declaration entry in the database.
507507
*
508508
* This class exists to work around the fact that `DeclStmt`s in some cases
509-
* do not have `DeclarationEntry`s. Currently, this is the case for:
510-
* - `DeclStmt`s in template instantiations.
509+
* do not have `DeclarationEntry`s in older databases.
511510
*
512511
* So instead, the IR works with `IRDeclarationEntry`s that synthesize missing
513512
* `DeclarationEntry`s when there is no result for `DeclStmt::getDeclarationEntry`.

cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll

Lines changed: 148 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,32 @@ class IteratorCrementNonMemberOperator extends Operator {
123123
}
124124

125125
private class IteratorCrementNonMemberOperatorModel extends IteratorCrementNonMemberOperator,
126-
DataFlowFunction
126+
DataFlowFunction, SideEffectFunction, AliasFunction
127127
{
128128
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
129129
input = getIteratorArgumentInput(this, 0) and
130130
output.isReturnValue()
131131
or
132132
input.isParameterDeref(0) and output.isReturnValueDeref()
133133
}
134+
135+
override predicate hasOnlySpecificReadSideEffects() { any() }
136+
137+
override predicate hasOnlySpecificWriteSideEffects() { any() }
138+
139+
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
140+
i = 0 and buffer = false
141+
}
142+
143+
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
144+
// See the comment on `IteratorCrementMemberOperatorModel::hasSpecificWriteSideEffect`
145+
// for an explanation of these values.
146+
i = 0 and buffer = false and mustWrite = false
147+
}
148+
149+
override predicate parameterNeverEscapes(int index) { none() }
150+
151+
override predicate parameterEscapesOnlyViaReturn(int index) { index = 0 }
134152
}
135153

136154
/**
@@ -146,7 +164,7 @@ class IteratorCrementMemberOperator extends MemberFunction {
146164
}
147165

148166
private class IteratorCrementMemberOperatorModel extends IteratorCrementMemberOperator,
149-
DataFlowFunction, TaintFunction
167+
DataFlowFunction, TaintFunction, SideEffectFunction, AliasFunction
150168
{
151169
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
152170
input.isQualifierAddress() and
@@ -163,6 +181,28 @@ private class IteratorCrementMemberOperatorModel extends IteratorCrementMemberOp
163181
input.isQualifierObject() and
164182
output.isReturnValueDeref()
165183
}
184+
185+
override predicate hasOnlySpecificReadSideEffects() { any() }
186+
187+
override predicate hasOnlySpecificWriteSideEffects() { any() }
188+
189+
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
190+
i = -1 and buffer = false
191+
}
192+
193+
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
194+
// We have two choices here: either `buffer` must be `true` or `mustWrite`
195+
// must be `false` to ensure that the IR alias analysis doesn't think that
196+
// `it++` completely override the value of the iterator.
197+
// We choose `mustWrite` must be `false`. In that case, the value of
198+
// `buffer` isn't super important (it just decides which kind of read side
199+
// effect will be emitted).
200+
i = -1 and buffer = false and mustWrite = false
201+
}
202+
203+
override predicate parameterNeverEscapes(int index) { index = -1 }
204+
205+
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
166206
}
167207

168208
/**
@@ -332,7 +372,7 @@ class IteratorAssignArithmeticOperator extends Function {
332372
* non-member and member versions, use `IteratorPointerDereferenceOperator`.
333373
*/
334374
class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunction,
335-
IteratorReferenceFunction
375+
IteratorReferenceFunction, AliasFunction, SideEffectFunction
336376
{
337377
IteratorPointerDereferenceMemberOperator() {
338378
this.getClassAndName("operator*") instanceof Iterator
@@ -345,6 +385,18 @@ class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunc
345385
input.isReturnValueDeref() and
346386
output.isQualifierObject()
347387
}
388+
389+
override predicate parameterNeverEscapes(int index) { index = -1 }
390+
391+
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
392+
393+
override predicate hasOnlySpecificReadSideEffects() { any() }
394+
395+
override predicate hasOnlySpecificWriteSideEffects() { any() }
396+
397+
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
398+
i = -1 and buffer = false
399+
}
348400
}
349401

350402
/**
@@ -361,7 +413,7 @@ class IteratorPointerDereferenceNonMemberOperator extends Operator, IteratorRefe
361413
}
362414

363415
private class IteratorPointerDereferenceNonMemberOperatorModel extends IteratorPointerDereferenceNonMemberOperator,
364-
TaintFunction
416+
TaintFunction, AliasFunction, SideEffectFunction
365417
{
366418
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
367419
input = getIteratorArgumentInput(this, 0) and
@@ -370,6 +422,18 @@ private class IteratorPointerDereferenceNonMemberOperatorModel extends IteratorP
370422
input.isReturnValueDeref() and
371423
output.isParameterDeref(0)
372424
}
425+
426+
override predicate parameterNeverEscapes(int index) { index = 0 }
427+
428+
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
429+
430+
override predicate hasOnlySpecificReadSideEffects() { any() }
431+
432+
override predicate hasOnlySpecificWriteSideEffects() { any() }
433+
434+
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
435+
i = 0 and buffer = false
436+
}
373437
}
374438

375439
/**
@@ -420,6 +484,71 @@ class IteratorAssignmentMemberOperator extends MemberFunction {
420484
}
421485
}
422486

487+
/**
488+
* A member `operator==` or `operator!=` function for an iterator type.
489+
*
490+
* Note that this class _only_ matches member functions. To find both
491+
* non-member and member versions, use `IteratorLogicalOperator`.
492+
*/
493+
class IteratorLogicalMemberOperator extends MemberFunction {
494+
IteratorLogicalMemberOperator() {
495+
this.getClassAndName(["operator!=", "operator=="]) instanceof Iterator
496+
}
497+
}
498+
499+
private class IteratorLogicalMemberOperatorModel extends IteratorLogicalMemberOperator,
500+
AliasFunction, SideEffectFunction
501+
{
502+
override predicate parameterNeverEscapes(int index) { index = [-1, 0] }
503+
504+
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
505+
506+
override predicate hasOnlySpecificReadSideEffects() { any() }
507+
508+
override predicate hasOnlySpecificWriteSideEffects() { any() }
509+
510+
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
511+
i = -1 and buffer = false
512+
}
513+
}
514+
515+
/**
516+
* A member `operator==` or `operator!=` function for an iterator type.
517+
*
518+
* Note that this class _only_ matches non-member functions. To find both
519+
* non-member and member versions, use `IteratorLogicalOperator`.
520+
*/
521+
class IteratorLogicalNonMemberOperator extends Function {
522+
IteratorLogicalNonMemberOperator() {
523+
this.hasName(["operator!=", "operator=="]) and
524+
exists(getIteratorArgumentInput(this, 0)) and
525+
exists(getIteratorArgumentInput(this, 1))
526+
}
527+
}
528+
529+
private class IteratorLogicalNonMemberOperatorModel extends IteratorLogicalNonMemberOperator,
530+
AliasFunction, SideEffectFunction
531+
{
532+
override predicate parameterNeverEscapes(int index) { index = [0, 1] }
533+
534+
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
535+
536+
override predicate hasOnlySpecificReadSideEffects() { any() }
537+
538+
override predicate hasOnlySpecificWriteSideEffects() { any() }
539+
}
540+
541+
/**
542+
* A (member or non-member) `operator==` or `operator!=` function for an iterator type.
543+
*/
544+
class IteratorLogicalOperator extends Function {
545+
IteratorLogicalOperator() {
546+
this instanceof IteratorLogicalNonMemberOperator
547+
or
548+
this instanceof IteratorLogicalMemberOperator
549+
}
550+
}
551+
423552
/**
424553
* An `operator=` member function of an iterator class that is not a copy or move assignment
425554
* operator.
@@ -428,12 +557,26 @@ class IteratorAssignmentMemberOperator extends MemberFunction {
428557
* `operator*` and use their own `operator=` to assign to the container.
429558
*/
430559
private class IteratorAssignmentMemberOperatorModel extends IteratorAssignmentMemberOperator,
431-
TaintFunction
560+
TaintFunction, SideEffectFunction, AliasFunction
432561
{
433562
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
434563
input.isParameterDeref(0) and
435564
output.isQualifierObject()
436565
}
566+
567+
override predicate hasOnlySpecificReadSideEffects() { any() }
568+
569+
override predicate hasOnlySpecificWriteSideEffects() { any() }
570+
571+
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
572+
// See the comment on `IteratorCrementMemberOperatorModel::hasSpecificWriteSideEffect`
573+
// for an explanation of these values.
574+
i = -1 and buffer = false and mustWrite = false
575+
}
576+
577+
override predicate parameterNeverEscapes(int index) { index = 0 }
578+
579+
override predicate parameterEscapesOnlyViaReturn(int index) { index = -1 }
437580
}
438581

439582
/**

cpp/ql/test/library-tests/CPP-205/elements.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
| CPP-205.cpp:2:15:5:1 | { ... } | isFromUninstantiatedTemplate(fn) |
1111
| CPP-205.cpp:3:3:3:33 | declaration | isFromTemplateInstantiation(fn) |
1212
| CPP-205.cpp:3:3:3:33 | declaration | isFromUninstantiatedTemplate(fn) |
13+
| CPP-205.cpp:3:15:3:15 | declaration of y | isFromTemplateInstantiation(fn) |
1314
| CPP-205.cpp:3:15:3:15 | declaration of y | isFromUninstantiatedTemplate(fn) |
15+
| CPP-205.cpp:3:15:3:15 | y | isFromTemplateInstantiation(fn) |
1416
| CPP-205.cpp:3:15:3:15 | y | isFromUninstantiatedTemplate(fn) |
1517
| CPP-205.cpp:3:17:3:31 | 5 | isFromTemplateInstantiation(fn) |
1618
| CPP-205.cpp:4:3:4:11 | return ... | isFromTemplateInstantiation(fn) |

0 commit comments

Comments
 (0)