Skip to content

Commit 54b30f5

Browse files
authored
Merge pull request github#1611 from ian-semmle/lambda
C++: Follow changes to how lambdas are extracted
2 parents a1b4d09 + b2a68d7 commit 54b30f5

File tree

8 files changed

+7651
-3533
lines changed

8 files changed

+7651
-3533
lines changed

cpp/ql/src/semmle/code/cpp/exprs/Lambda.qll

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class LambdaExpression extends Expr, @lambdaexpr {
2424
* Gets the nth implicitly or explicitly captured value of this lambda expression.
2525
*/
2626
LambdaCapture getCapture(int index) {
27-
lambda_capture(result, underlyingElement(this), index, _, _, _)
27+
lambda_capture(result, underlyingElement(this), index, _, _, _, _)
2828
}
2929

3030
/**
@@ -64,7 +64,7 @@ class LambdaExpression extends Expr, @lambdaexpr {
6464
* Gets the initializer that initializes the captured variables in the closure, if any.
6565
* A lambda that does not capture any variables will not have an initializer.
6666
*/
67-
Expr getInitializer() {
67+
ClassAggregateLiteral getInitializer() {
6868
result = getChild(0)
6969
}
7070
}
@@ -109,7 +109,7 @@ class LambdaCapture extends @lambdacapture {
109109
* Holds if this capture was made implicitly.
110110
*/
111111
predicate isImplicit() {
112-
lambda_capture(this, _, _, _, true, _)
112+
lambda_capture(this, _, _, _, _, true, _)
113113
}
114114

115115
/**
@@ -122,7 +122,7 @@ class LambdaCapture extends @lambdacapture {
122122
* is actually "*this" being captured rather than "this".]
123123
*/
124124
predicate isCapturedByReference() {
125-
lambda_capture(this, _, _, true, _, _)
125+
lambda_capture(this, _, _, _, true, _, _)
126126
}
127127

128128
/**
@@ -134,16 +134,14 @@ class LambdaCapture extends @lambdacapture {
134134
* expression which accesses the captured variable.
135135
*/
136136
Location getLocation() {
137-
lambda_capture(this, _, _, _, _, result)
137+
lambda_capture(this, _, _, _, _, _, result)
138138
}
139139

140140
/**
141141
* Gets the field of the lambda expression's closure type which is used to store this capture.
142142
*/
143143
MemberVariable getField() {
144-
exists(LambdaExpression lambda, int index | this = lambda.getCapture(index) |
145-
result = lambda.getType().(Closure).getCanonicalMember(index)
146-
)
144+
lambda_capture(this, _, _, result, _, _, _)
147145
}
148146

149147
/**
@@ -154,9 +152,8 @@ class LambdaCapture extends @lambdacapture {
154152
* For by-value captures of non-primitive types, this will be a call to a copy constructor.
155153
*/
156154
Expr getInitializer() {
157-
exists(LambdaExpression lambda, int index | this = lambda.getCapture(index) |
158-
result = lambda.getChild(0) // Call to the constructor of the closure type.
159-
.getChild(index) // The appropriate argument to the constructor.
155+
exists(LambdaExpression lambda | this = lambda.getCapture(_) |
156+
result = lambda.getInitializer().getFieldExpr(this.getField())
160157
)
161158
}
162159
}

cpp/ql/src/semmlecode.cpp.dbscheme

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,6 +1579,7 @@ lambda_capture(
15791579
unique int id: @lambdacapture,
15801580
int lambda: @lambdaexpr ref,
15811581
int index: int ref,
1582+
int field: @membervariable ref,
15821583
boolean captured_by_reference: boolean ref,
15831584
boolean is_implicit: boolean ref,
15841585
int ___location: @location_default ref

0 commit comments

Comments
 (0)