Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 578ed14

Browse files
authored
Merge pull request #1115 from dave-bartolomeo/dave/Lambdas
C++: IR construction for lambda expressions
2 parents 59285be + e25c578 commit 578ed14

10 files changed

Lines changed: 1446 additions & 84 deletions

File tree

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ class LambdaExpression extends Expr, @lambdaexpr {
5757
Operator getLambdaFunction() {
5858
result = getType().(Closure).getLambdaFunction()
5959
}
60+
61+
/**
62+
* Gets the initializer that initializes the captured variables in the closure, if any.
63+
* A lambda that does not capture any variables will not have an initializer.
64+
*/
65+
Expr getInitializer() {
66+
result = getChild(0)
67+
}
6068
}
6169

6270
/**

cpp/ql/src/semmle/code/cpp/ir/implementation/TempVariableTag.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ private import semmle.code.cpp.ir.internal.TempVariableTag
33

44
class TempVariableTag extends TTempVariableTag {
55
string toString() {
6-
result = "Tag"
6+
result = getTempVariableTagId(this)
77
}
88
}

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class InstructionTag extends TInstructionTag {
9999
string getInstructionTagId(TInstructionTag tag) {
100100
tag = OnlyInstructionTag() and result = "Only" or // Single instruction (not including implicit Load)
101101
tag = InitializerVariableAddressTag() and result = "InitVarAddr" or
102+
tag = InitializerLoadStringTag() and result = "InitLoadStr" or
102103
tag = InitializerStoreTag() and result = "InitStore" or
103104
tag = InitializerUninitializedTag() and result = "InitUninit" or
104105
tag = ZeroPadStringConstantTag() and result = "ZeroPadConst" or

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,9 @@ newtype TTranslatedElement =
268268
) or
269269
exists(ThrowExpr throw |
270270
throw.getExpr().getFullyConverted() = expr
271+
) or
272+
exists(LambdaExpression lambda |
273+
lambda.getInitializer().getFullyConverted() = expr
271274
)
272275
)
273276
} or

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2608,3 +2608,122 @@ class TranslatedConditionDeclExpr extends TranslatedNonConstantExpr {
26082608
result = getTranslatedExpr(expr.getVariableAccess().getFullyConverted())
26092609
}
26102610
}
2611+
2612+
/**
2613+
* The IR translation of a lambda expression. This initializes a temporary variable whose type is that of the lambda,
2614+
* using the initializer list that represents the captures of the lambda.
2615+
*/
2616+
class TranslatedLambdaExpr extends TranslatedNonConstantExpr, InitializationContext {
2617+
override LambdaExpression expr;
2618+
2619+
override final Instruction getFirstInstruction() {
2620+
result = getInstruction(InitializerVariableAddressTag())
2621+
}
2622+
2623+
override final TranslatedElement getChild(int id) {
2624+
id = 0 and result = getInitialization()
2625+
}
2626+
2627+
override Instruction getResult() {
2628+
result = getInstruction(LoadTag())
2629+
}
2630+
2631+
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
2632+
(
2633+
tag = InitializerVariableAddressTag() and
2634+
kind instanceof GotoEdge and
2635+
result = getInstruction(InitializerStoreTag())
2636+
) or
2637+
(
2638+
tag = InitializerStoreTag() and
2639+
kind instanceof GotoEdge and
2640+
(
2641+
result = getInitialization().getFirstInstruction() or
2642+
not hasInitializer() and result = getInstruction(LoadTag())
2643+
)
2644+
) or
2645+
(
2646+
tag = LoadTag() and
2647+
kind instanceof GotoEdge and
2648+
result = getParent().getChildSuccessor(this)
2649+
)
2650+
}
2651+
2652+
override Instruction getChildSuccessor(TranslatedElement child) {
2653+
child = getInitialization() and
2654+
result = getInstruction(LoadTag())
2655+
}
2656+
2657+
override predicate hasInstruction(Opcode opcode, InstructionTag tag, Type resultType,
2658+
boolean isGLValue) {
2659+
(
2660+
tag = InitializerVariableAddressTag() and
2661+
opcode instanceof Opcode::VariableAddress and
2662+
resultType = getResultType() and
2663+
isGLValue = true
2664+
) or
2665+
(
2666+
tag = InitializerStoreTag() and
2667+
opcode instanceof Opcode::Uninitialized and
2668+
resultType = getResultType() and
2669+
isGLValue = false
2670+
) or
2671+
(
2672+
tag = LoadTag() and
2673+
opcode instanceof Opcode::Load and
2674+
resultType = getResultType() and
2675+
isGLValue = false
2676+
)
2677+
}
2678+
2679+
override Instruction getInstructionOperand(InstructionTag tag,
2680+
OperandTag operandTag) {
2681+
(
2682+
tag = InitializerStoreTag() and
2683+
operandTag instanceof AddressOperandTag and
2684+
result = getInstruction(InitializerVariableAddressTag())
2685+
) or
2686+
(
2687+
tag = LoadTag() and
2688+
(
2689+
(
2690+
operandTag instanceof AddressOperandTag and
2691+
result = getInstruction(InitializerVariableAddressTag())
2692+
) or
2693+
(
2694+
operandTag instanceof LoadOperandTag and
2695+
result = getEnclosingFunction().getUnmodeledDefinitionInstruction()
2696+
)
2697+
)
2698+
)
2699+
}
2700+
2701+
override IRVariable getInstructionVariable(InstructionTag tag) {
2702+
(
2703+
tag = InitializerVariableAddressTag() or
2704+
tag = InitializerStoreTag()
2705+
) and
2706+
result = getTempVariable(LambdaTempVar())
2707+
}
2708+
2709+
override predicate hasTempVariable(TempVariableTag tag, Type type) {
2710+
tag = LambdaTempVar() and
2711+
type = getResultType()
2712+
}
2713+
2714+
override final Instruction getTargetAddress() {
2715+
result = getInstruction(InitializerVariableAddressTag())
2716+
}
2717+
2718+
override final Type getTargetType() {
2719+
result = getResultType()
2720+
}
2721+
2722+
private predicate hasInitializer() {
2723+
exists(getInitialization())
2724+
}
2725+
2726+
private TranslatedInitialization getInitialization() {
2727+
result = getTranslatedInitialization(expr.getChild(0).getFullyConverted())
2728+
}
2729+
}

0 commit comments

Comments
 (0)