Merge pull request #1611 from ian-semmle/lambda

C++: Follow changes to how lambdas are extracted
This commit is contained in:
Nick Rolfe
2019-07-29 10:52:50 +01:00
committed by GitHub
8 changed files with 7655 additions and 3537 deletions

View File

@@ -24,7 +24,7 @@ class LambdaExpression extends Expr, @lambdaexpr {
* Gets the nth implicitly or explicitly captured value of this lambda expression.
*/
LambdaCapture getCapture(int index) {
lambda_capture(result, underlyingElement(this), index, _, _, _)
lambda_capture(result, underlyingElement(this), index, _, _, _, _)
}
/**
@@ -64,7 +64,7 @@ class LambdaExpression extends Expr, @lambdaexpr {
* Gets the initializer that initializes the captured variables in the closure, if any.
* A lambda that does not capture any variables will not have an initializer.
*/
Expr getInitializer() {
ClassAggregateLiteral getInitializer() {
result = getChild(0)
}
}
@@ -109,7 +109,7 @@ class LambdaCapture extends @lambdacapture {
* Holds if this capture was made implicitly.
*/
predicate isImplicit() {
lambda_capture(this, _, _, _, true, _)
lambda_capture(this, _, _, _, _, true, _)
}
/**
@@ -122,7 +122,7 @@ class LambdaCapture extends @lambdacapture {
* is actually "*this" being captured rather than "this".]
*/
predicate isCapturedByReference() {
lambda_capture(this, _, _, true, _, _)
lambda_capture(this, _, _, _, true, _, _)
}
/**
@@ -134,16 +134,14 @@ class LambdaCapture extends @lambdacapture {
* expression which accesses the captured variable.
*/
Location getLocation() {
lambda_capture(this, _, _, _, _, result)
lambda_capture(this, _, _, _, _, _, result)
}
/**
* Gets the field of the lambda expression's closure type which is used to store this capture.
*/
MemberVariable getField() {
exists(LambdaExpression lambda, int index | this = lambda.getCapture(index) |
result = lambda.getType().(Closure).getCanonicalMember(index)
)
lambda_capture(this, _, _, result, _, _, _)
}
/**
@@ -154,9 +152,8 @@ class LambdaCapture extends @lambdacapture {
* For by-value captures of non-primitive types, this will be a call to a copy constructor.
*/
Expr getInitializer() {
exists(LambdaExpression lambda, int index | this = lambda.getCapture(index) |
result = lambda.getChild(0) // Call to the constructor of the closure type.
.getChild(index) // The appropriate argument to the constructor.
exists(LambdaExpression lambda | this = lambda.getCapture(_) |
result = lambda.getInitializer().getFieldExpr(this.getField())
)
}
}

View File

@@ -1579,6 +1579,7 @@ lambda_capture(
unique int id: @lambdacapture,
int lambda: @lambdaexpr ref,
int index: int ref,
int field: @membervariable ref,
boolean captured_by_reference: boolean ref,
boolean is_implicit: boolean ref,
int location: @location_default ref

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
| captures.cpp:3:6:3:6 | x | explicit | 1 |
| captures.cpp:3:9:3:12 | (captured this) | explicit | 2 |
| captures.cpp:10:7:10:7 | (captured this) | implicit | 1 |
| captures.cpp:10:9:10:9 | x | implicit | 2 |
| captures.cpp:15:6:15:6 | x | explicit | 1 |
| end_pos.cpp:9:17:9:18 | ii | explicit | 1 |
| captures.cpp:3:6:3:6 | x | explicit | 0 |
| captures.cpp:3:9:3:12 | (captured this) | explicit | 1 |
| captures.cpp:10:7:10:7 | (captured this) | implicit | 0 |
| captures.cpp:10:9:10:9 | x | implicit | 1 |
| captures.cpp:15:6:15:6 | x | explicit | 0 |
| end_pos.cpp:9:17:9:18 | ii | explicit | 0 |

View File

@@ -0,0 +1,15 @@
class LambdaCapture extends @lambdacapture { string toString() { none() } }
class Lambda extends @lambdaexpr { string toString() { none() } }
class Field extends @membervariable { string toString() { none() } }
class Location extends @location_default { string toString() { none() } }
class Type extends @usertype { string toString() { none() } }
from LambdaCapture lc, Lambda l, int i, Field f,
boolean captured_by_reference, boolean is_implicit,
Location loc, Type t
where lambda_capture(lc, l, i, captured_by_reference, is_implicit, loc)
and expr_types(l, t, _)
and member(t, i, f)
select lc, l, i, f, captured_by_reference, is_implicit, loc

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
description: Add field to lambda_capture
compatibility: backwards
lambda_capture.rel: run lambda_capture.qlo