Skip to content

Commit feb31d2

Browse files
Merge branch 'main' into 17052-second-try-do-not-expose-error-message
2 parents 1c1ba77 + 91f5f08 commit feb31d2

File tree

66 files changed

+3208
-1281
lines changed

Some content is hidden

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

66 files changed

+3208
-1281
lines changed

cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -215,19 +215,16 @@ predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { none() }
215215
predicate localMustFlowStep(Node node1, Node node2) { none() }
216216

217217
/** Gets the type of `n` used for type pruning. */
218-
Type getNodeType(Node n) {
218+
DataFlowType getNodeType(Node n) {
219219
exists(n) and
220220
result instanceof VoidType // stub implementation
221221
}
222222

223-
/** Gets a string representation of a type returned by `getNodeType`. */
224-
string ppReprType(Type t) { none() } // stub implementation
225-
226223
/**
227224
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from
228225
* a node of type `t1` to a node of type `t2`.
229226
*/
230-
predicate compatibleTypes(Type t1, Type t2) {
227+
predicate compatibleTypes(DataFlowType t1, DataFlowType t2) {
231228
t1 instanceof VoidType and t2 instanceof VoidType // stub implementation
232229
}
233230

@@ -243,7 +240,11 @@ class DataFlowCallable extends Function { }
243240

244241
class DataFlowExpr = Expr;
245242

246-
class DataFlowType = Type;
243+
final private class TypeFinal = Type;
244+
245+
class DataFlowType extends TypeFinal {
246+
string toString() { result = "" }
247+
}
247248

248249
/** A function call relevant for data flow. */
249250
class DataFlowCall extends Expr instanceof Call {

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -994,9 +994,6 @@ DataFlowType getNodeType(Node n) {
994994
result instanceof VoidType // stub implementation
995995
}
996996

997-
/** Gets a string representation of a type returned by `getNodeType`. */
998-
string ppReprType(DataFlowType t) { none() } // stub implementation
999-
1000997
/**
1001998
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from
1002999
* a node of type `t1` to a node of type `t2`.
@@ -1097,7 +1094,11 @@ class SummarizedCallable extends DataFlowCallable, TSummarizedCallable {
10971094

10981095
class DataFlowExpr = Expr;
10991096

1100-
class DataFlowType = Type;
1097+
final private class TypeFinal = Type;
1098+
1099+
class DataFlowType extends TypeFinal {
1100+
string toString() { result = "" }
1101+
}
11011102

11021103
cached
11031104
private newtype TDataFlowCall =

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

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,56 @@ private predicate resultEscapesNonReturn(Instruction instr) {
338338
not instr.isResultModeled()
339339
}
340340

341+
/** Holds if `operand` may (transitively) flow to an `AddressOperand`. */
342+
private predicate consumedAsAddressOperand(Operand operand) {
343+
operand instanceof AddressOperand
344+
or
345+
exists(Operand address |
346+
consumedAsAddressOperand(address) and
347+
operandIsPropagated(operand, _, address.getDef())
348+
)
349+
}
350+
351+
/**
352+
* Holds if `operand` may originate from a base instruction of an allocation,
353+
* and that operand may transitively flow to an `AddressOperand`.
354+
*/
355+
private predicate propagatedFromAllocationBase(Operand operand, Configuration::Allocation allocation) {
356+
consumedAsAddressOperand(operand) and
357+
(
358+
not exists(Configuration::getOldAllocation(allocation)) and
359+
operand.getDef() = allocation.getABaseInstruction()
360+
or
361+
exists(Operand address |
362+
operandIsPropagated(address, _, operand.getDef()) and
363+
propagatedFromAllocationBase(address, allocation)
364+
)
365+
)
366+
}
367+
368+
private predicate propagatedFromNonAllocationBase(Operand operand) {
369+
exists(Instruction def |
370+
def = operand.getDef() and
371+
not operandIsPropagated(_, _, def) and
372+
not def = any(Configuration::Allocation allocation).getABaseInstruction()
373+
)
374+
or
375+
exists(Operand address |
376+
operandIsPropagated(address, _, operand.getDef()) and
377+
propagatedFromNonAllocationBase(address)
378+
)
379+
}
380+
381+
/**
382+
* Holds if we cannot see all producers of an operand for which allocation also flows into.
383+
*/
384+
private predicate operandConsumesEscaped(Configuration::Allocation allocation) {
385+
exists(AddressOperand address |
386+
propagatedFromAllocationBase(address, allocation) and
387+
propagatedFromNonAllocationBase(address)
388+
)
389+
}
390+
341391
/**
342392
* Holds if the address of `allocation` escapes outside the domain of the analysis. This can occur
343393
* either because the allocation's address is taken within the function and escapes, or because the
@@ -346,12 +396,14 @@ private predicate resultEscapesNonReturn(Instruction instr) {
346396
predicate allocationEscapes(Configuration::Allocation allocation) {
347397
allocation.alwaysEscapes()
348398
or
349-
exists(IREscapeAnalysisConfiguration config |
350-
config.useSoundEscapeAnalysis() and resultEscapesNonReturn(allocation.getABaseInstruction())
399+
exists(IREscapeAnalysisConfiguration config | config.useSoundEscapeAnalysis() |
400+
resultEscapesNonReturn(allocation.getABaseInstruction())
401+
or
402+
operandConsumesEscaped(allocation)
351403
)
352404
or
353405
Configuration::phaseNeedsSoundEscapeAnalysis() and
354-
resultEscapesNonReturn(allocation.getABaseInstruction())
406+
(resultEscapesNonReturn(allocation.getABaseInstruction()) or operandConsumesEscaped(allocation))
355407
}
356408

357409
/**

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,8 @@ class DynamicAllocation extends Allocation, TDynamicAllocation {
146146
}
147147

148148
predicate phaseNeedsSoundEscapeAnalysis() { none() }
149+
150+
UnaliasedSsa::Allocation getOldAllocation(VariableAllocation allocation) {
151+
UnaliasedSsa::canReuseSsaForVariable(allocation.getIRVariable()) and
152+
result = allocation.getIRVariable()
153+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ private import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSAConst
77
private import semmle.code.cpp.ir.internal.IntegerConstant as Ints
88
private import semmle.code.cpp.ir.internal.IntegerInterval as Interval
99
private import semmle.code.cpp.ir.implementation.internal.OperandTag
10-
private import AliasConfiguration
10+
import AliasConfiguration
1111
private import codeql.util.Boolean
1212

1313
private class IntValue = Ints::IntValue;

cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,56 @@ private predicate resultEscapesNonReturn(Instruction instr) {
338338
not instr.isResultModeled()
339339
}
340340

341+
/** Holds if `operand` may (transitively) flow to an `AddressOperand`. */
342+
private predicate consumedAsAddressOperand(Operand operand) {
343+
operand instanceof AddressOperand
344+
or
345+
exists(Operand address |
346+
consumedAsAddressOperand(address) and
347+
operandIsPropagated(operand, _, address.getDef())
348+
)
349+
}
350+
351+
/**
352+
* Holds if `operand` may originate from a base instruction of an allocation,
353+
* and that operand may transitively flow to an `AddressOperand`.
354+
*/
355+
private predicate propagatedFromAllocationBase(Operand operand, Configuration::Allocation allocation) {
356+
consumedAsAddressOperand(operand) and
357+
(
358+
not exists(Configuration::getOldAllocation(allocation)) and
359+
operand.getDef() = allocation.getABaseInstruction()
360+
or
361+
exists(Operand address |
362+
operandIsPropagated(address, _, operand.getDef()) and
363+
propagatedFromAllocationBase(address, allocation)
364+
)
365+
)
366+
}
367+
368+
private predicate propagatedFromNonAllocationBase(Operand operand) {
369+
exists(Instruction def |
370+
def = operand.getDef() and
371+
not operandIsPropagated(_, _, def) and
372+
not def = any(Configuration::Allocation allocation).getABaseInstruction()
373+
)
374+
or
375+
exists(Operand address |
376+
operandIsPropagated(address, _, operand.getDef()) and
377+
propagatedFromNonAllocationBase(address)
378+
)
379+
}
380+
381+
/**
382+
* Holds if we cannot see all producers of an operand for which allocation also flows into.
383+
*/
384+
private predicate operandConsumesEscaped(Configuration::Allocation allocation) {
385+
exists(AddressOperand address |
386+
propagatedFromAllocationBase(address, allocation) and
387+
propagatedFromNonAllocationBase(address)
388+
)
389+
}
390+
341391
/**
342392
* Holds if the address of `allocation` escapes outside the domain of the analysis. This can occur
343393
* either because the allocation's address is taken within the function and escapes, or because the
@@ -346,12 +396,14 @@ private predicate resultEscapesNonReturn(Instruction instr) {
346396
predicate allocationEscapes(Configuration::Allocation allocation) {
347397
allocation.alwaysEscapes()
348398
or
349-
exists(IREscapeAnalysisConfiguration config |
350-
config.useSoundEscapeAnalysis() and resultEscapesNonReturn(allocation.getABaseInstruction())
399+
exists(IREscapeAnalysisConfiguration config | config.useSoundEscapeAnalysis() |
400+
resultEscapesNonReturn(allocation.getABaseInstruction())
401+
or
402+
operandConsumesEscaped(allocation)
351403
)
352404
or
353405
Configuration::phaseNeedsSoundEscapeAnalysis() and
354-
resultEscapesNonReturn(allocation.getABaseInstruction())
406+
(resultEscapesNonReturn(allocation.getABaseInstruction()) or operandConsumesEscaped(allocation))
355407
}
356408

357409
/**

cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasConfiguration.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
private import AliasConfigurationImports
2+
private import codeql.util.Unit
23

34
/**
45
* A memory allocation that can be tracked by the SimpleSSA alias analysis.
@@ -16,3 +17,5 @@ class Allocation extends IRAutomaticVariable {
1617
}
1718

1819
predicate phaseNeedsSoundEscapeAnalysis() { any() }
20+
21+
Unit getOldAllocation(Allocation allocation) { any() }

cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import AliasAnalysis
22
private import SimpleSSAImports
33
import SimpleSSAPublicImports
4-
private import AliasConfiguration
4+
import AliasConfiguration
55
private import codeql.util.Unit
66

77
private predicate isTotalAccess(Allocation var, AddressOperand addrOperand, IRType type) {

cpp/ql/lib/semmle/code/cpp/models/Models.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ private import implementations.StdPair
2727
private import implementations.StdMap
2828
private import implementations.StdSet
2929
private import implementations.StdString
30+
private import implementations.StdFunction
31+
private import implementations.StdException
32+
private import implementations.StdAllocator
33+
private import implementations.StdAlgorithm
34+
private import implementations.StdMath
3035
private import implementations.Swap
3136
private import implementations.GetDelim
3237
private import implementations.SmartPointer

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

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,41 @@ private class StdIterator extends Iterator, Class {
8686
override Type getValueType() { result = this.getTemplateArgument(1).(Type).getUnderlyingType() }
8787
}
8888

89+
private class StdReverseIterator extends Iterator, Class {
90+
StdReverseIterator() { this.hasQualifiedName(["std", "bsl"], "reverse_iterator") }
91+
92+
override Type getValueType() { result = this.getTemplateArgument(1).(Type).getUnderlyingType() }
93+
}
94+
95+
private class StdIstreamBufIterator extends Iterator, Class {
96+
StdIstreamBufIterator() { this.hasQualifiedName(["std", "bsl"], "istreambuf_iterator") }
97+
98+
override Type getValueType() { result = this.getTemplateArgument(1).(Type).getUnderlyingType() }
99+
}
100+
101+
private class StdIstreambufIteratorConstructor extends Constructor, SideEffectFunction,
102+
AliasFunction
103+
{
104+
StdIstreambufIteratorConstructor() { this.getDeclaringType() instanceof StdIstreamBufIterator }
105+
106+
override predicate parameterNeverEscapes(int index) { index = -1 }
107+
108+
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
109+
110+
override predicate hasOnlySpecificReadSideEffects() { any() }
111+
112+
override predicate hasOnlySpecificWriteSideEffects() { any() }
113+
114+
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
115+
i = -1 and buffer = false and mustWrite = true
116+
}
117+
118+
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
119+
this.getParameter(i).getUnspecifiedType() instanceof ReferenceType and
120+
buffer = false
121+
}
122+
}
123+
89124
/**
90125
* Gets the `FunctionInput` corresponding to an iterator parameter to
91126
* user-defined operator `op`, at `index`.
@@ -579,31 +614,51 @@ private class IteratorAssignmentMemberOperatorModel extends IteratorAssignmentMe
579614
override predicate parameterEscapesOnlyViaReturn(int index) { index = -1 }
580615
}
581616

617+
private string beginName() {
618+
result = ["begin", "cbegin", "rbegin", "crbegin", "before_begin", "cbefore_begin"]
619+
}
620+
582621
/**
583622
* A `begin` member function, or a related function, that returns an iterator.
584623
*/
585-
class BeginFunction extends MemberFunction {
624+
class BeginFunction extends Function {
586625
BeginFunction() {
587-
this.hasName(["begin", "cbegin", "rbegin", "crbegin", "before_begin", "cbefore_begin"]) and
588-
this.getType().getUnspecifiedType() instanceof Iterator
626+
this.getUnspecifiedType() instanceof Iterator and
627+
(
628+
this.hasName(beginName()) and
629+
this instanceof MemberFunction
630+
or
631+
this.hasGlobalOrStdOrBslName(beginName()) and
632+
not this instanceof MemberFunction and
633+
this.getNumberOfParameters() = 1
634+
)
589635
}
590636
}
591637

638+
private string endName() { result = ["end", "cend", "rend", "crend"] }
639+
592640
/**
593641
* An `end` member function, or a related function, that returns an iterator.
594642
*/
595-
class EndFunction extends MemberFunction {
643+
class EndFunction extends Function {
596644
EndFunction() {
597-
this.hasName(["end", "cend", "rend", "crend"]) and
598-
this.getType().getUnspecifiedType() instanceof Iterator
645+
this.getUnspecifiedType() instanceof Iterator and
646+
(
647+
this.hasName(endName()) and
648+
this instanceof MemberFunction
649+
or
650+
this.hasGlobalOrStdOrBslName(endName()) and
651+
this instanceof MemberFunction and
652+
this.getNumberOfParameters() = 1
653+
)
599654
}
600655
}
601656

602657
/**
603658
* A `begin` or `end` member function, or a related member function, that
604659
* returns an iterator.
605660
*/
606-
class BeginOrEndFunction extends MemberFunction {
661+
class BeginOrEndFunction extends Function {
607662
BeginOrEndFunction() {
608663
this instanceof BeginFunction or
609664
this instanceof EndFunction

0 commit comments

Comments
 (0)