Skip to content

Commit 999fb07

Browse files
committed
C++: Add more alias models.
1 parent 38aac1f commit 999fb07

File tree

12 files changed

+1314
-18
lines changed

12 files changed

+1314
-18
lines changed

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

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import semmle.code.cpp.models.interfaces.FormattingFunction
99
import semmle.code.cpp.models.interfaces.Alias
10+
import semmle.code.cpp.models.interfaces.SideEffect
1011

1112
/**
1213
* The standard functions `printf`, `wprintf` and their glib variants.
@@ -96,7 +97,7 @@ private class Sprintf extends FormattingFunction {
9697
/**
9798
* Implements `Snprintf`.
9899
*/
99-
private class SnprintfImpl extends Snprintf {
100+
private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction {
100101
SnprintfImpl() {
101102
this instanceof TopLevelFunction and
102103
(
@@ -143,6 +144,26 @@ private class SnprintfImpl extends Snprintf {
143144
}
144145

145146
override int getSizeParameterIndex() { result = 1 }
147+
148+
override predicate parameterNeverEscapes(int index) {
149+
// We don't know how many parameters are passed to the function since it's varargs, but they also don't escape.
150+
index = this.getFormatParameterIndex()
151+
}
152+
153+
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
154+
155+
override predicate hasOnlySpecificReadSideEffects() { any() }
156+
157+
override predicate hasOnlySpecificWriteSideEffects() { any() }
158+
159+
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
160+
i = this.getOutputParameterIndex(false) and buffer = true and mustWrite = false
161+
}
162+
163+
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
164+
// We don't know how many parameters are passed to the function since it's varargs, but they also have read side effects.
165+
i = this.getFormatParameterIndex() and buffer = true
166+
}
146167
}
147168

148169
/**
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/**
2+
* Provides models for C++ functions from the `algorithms` header.
3+
*/
4+
5+
import semmle.code.cpp.models.interfaces.Taint
6+
import semmle.code.cpp.models.interfaces.DataFlow
7+
import semmle.code.cpp.models.interfaces.Iterator
8+
import semmle.code.cpp.models.interfaces.SideEffect
9+
import semmle.code.cpp.models.interfaces.Alias
10+
11+
private class StdPartialSort extends Function, SideEffectFunction, AliasFunction {
12+
StdPartialSort() { this.hasGlobalOrStdName("partial_sort") }
13+
14+
override predicate hasOnlySpecificReadSideEffects() { any() }
15+
16+
override predicate hasOnlySpecificWriteSideEffects() { any() }
17+
18+
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
19+
i = this.getAnIteratorParameterIndex() and buffer = true and mustWrite = false
20+
}
21+
22+
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
23+
i = this.getAnIteratorParameterIndex() and
24+
buffer = true and
25+
this.getParameter(i).getUnspecifiedType() instanceof ReferenceType and
26+
buffer = false
27+
}
28+
29+
private int getAnIteratorParameterIndex() {
30+
this.getParameter(result).getUnspecifiedType() instanceof Iterator
31+
}
32+
33+
override predicate parameterNeverEscapes(int index) {
34+
index = this.getAnIteratorParameterIndex()
35+
or
36+
this.getParameter(index).getUnspecifiedType() instanceof ReferenceType
37+
}
38+
39+
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
40+
}
41+
42+
private class StdSortHeap extends Function, SideEffectFunction, AliasFunction {
43+
StdSortHeap() { this.hasGlobalOrStdName("sort_heap") }
44+
45+
override predicate hasOnlySpecificReadSideEffects() { any() }
46+
47+
override predicate hasOnlySpecificWriteSideEffects() { any() }
48+
49+
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
50+
i = this.getAnIteratorParameterIndex() and buffer = true and mustWrite = false
51+
}
52+
53+
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
54+
i = this.getAnIteratorParameterIndex() and
55+
buffer = true
56+
}
57+
58+
private int getAnIteratorParameterIndex() {
59+
this.getParameter(result).getUnspecifiedType() instanceof Iterator
60+
}
61+
62+
override predicate parameterNeverEscapes(int index) { index = this.getAnIteratorParameterIndex() }
63+
64+
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
65+
}
66+
67+
private class StdGenerateN extends Function, SideEffectFunction, AliasFunction {
68+
StdGenerateN() { this.hasGlobalOrStdName("generate_n") }
69+
70+
override predicate hasOnlySpecificReadSideEffects() { any() }
71+
72+
override predicate hasOnlySpecificWriteSideEffects() { any() }
73+
74+
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
75+
i = this.getAnIteratorParameterIndex() and buffer = true and mustWrite = false
76+
}
77+
78+
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
79+
this.getParameter(i).getUnspecifiedType() instanceof ReferenceType and buffer = false
80+
}
81+
82+
private int getAnIteratorParameterIndex() {
83+
this.getParameter(result).getUnspecifiedType() instanceof Iterator
84+
}
85+
86+
override predicate parameterNeverEscapes(int index) { index = this.getAnIteratorParameterIndex() }
87+
88+
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
89+
}
90+
91+
private class StdFindIfOrIfNot extends Function, SideEffectFunction, AliasFunction {
92+
StdFindIfOrIfNot() { this.hasGlobalOrStdName(["find_if", "find_if_not"]) }
93+
94+
override predicate hasOnlySpecificReadSideEffects() { any() }
95+
96+
override predicate hasOnlySpecificWriteSideEffects() { any() }
97+
98+
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
99+
i = this.getAnIteratorParameterIndex() and buffer = true
100+
or
101+
this.getParameter(i).getUnspecifiedType() instanceof ReferenceType and buffer = false
102+
}
103+
104+
private int getAnIteratorParameterIndex() {
105+
this.getParameter(result).getUnspecifiedType() instanceof Iterator
106+
}
107+
108+
override predicate parameterNeverEscapes(int index) {
109+
this.getParameter(index).getUnspecifiedType() instanceof ReferenceType
110+
}
111+
112+
override predicate parameterEscapesOnlyViaReturn(int index) {
113+
index = this.getAnIteratorParameterIndex()
114+
}
115+
}

0 commit comments

Comments
 (0)