Skip to content

Commit 6515e77

Browse files
committed
C++: Generate additional loads for non-reference structured bindings
1 parent eebfbc1 commit 6515e77

File tree

4 files changed

+153
-57
lines changed

4 files changed

+153
-57
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ newtype TInstructionTag =
7171
AsmTag() or
7272
AsmInputTag(int elementIndex) { exists(AsmStmt asm | exists(asm.getChild(elementIndex))) } or
7373
ThisAddressTag() or
74-
ThisLoadTag()
74+
ThisLoadTag() or
75+
StructuredBindingAccessTag()
7576

7677
class InstructionTag extends TInstructionTag {
7778
final string toString() { result = "Tag" }
@@ -221,4 +222,6 @@ string getInstructionTagId(TInstructionTag tag) {
221222
tag = ThisAddressTag() and result = "ThisAddress"
222223
or
223224
tag = ThisLoadTag() and result = "ThisLoad"
225+
or
226+
tag = StructuredBindingAccessTag() and result = "StructuredBindingAccess"
224227
}

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

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ private import semmle.code.cpp.ir.implementation.IRType
33
private import semmle.code.cpp.ir.implementation.Opcode
44
private import semmle.code.cpp.ir.implementation.internal.OperandTag
55
private import semmle.code.cpp.ir.internal.CppType
6+
private import semmle.code.cpp.ir.internal.IRUtilities
67
private import semmle.code.cpp.ir.internal.TempVariableTag
78
private import InstructionTag
89
private import TranslatedCondition
@@ -813,7 +814,9 @@ abstract class TranslatedVariableAccess extends TranslatedNonConstantExpr {
813814
}
814815

815816
class TranslatedNonFieldVariableAccess extends TranslatedVariableAccess {
816-
TranslatedNonFieldVariableAccess() { not expr instanceof FieldAccess }
817+
TranslatedNonFieldVariableAccess() {
818+
not expr instanceof FieldAccess and not isNonReferenceStructuredBinding(expr.getTarget())
819+
}
817820

818821
override Instruction getFirstInstruction() {
819822
if exists(this.getQualifier())
@@ -860,6 +863,61 @@ class TranslatedFieldAccess extends TranslatedVariableAccess {
860863
}
861864
}
862865

866+
class TranslatedStructuredBindingVariableAccess extends TranslatedNonConstantExpr {
867+
override VariableAccess expr;
868+
869+
TranslatedStructuredBindingVariableAccess() { isNonReferenceStructuredBinding(expr.getTarget()) }
870+
871+
override Instruction getFirstInstruction() {
872+
// Structured bindings cannot be qualified.
873+
result = this.getInstruction(StructuredBindingAccessTag())
874+
}
875+
876+
override TranslatedElement getChild(int id) {
877+
// Structured bindings cannot be qualified.
878+
none()
879+
}
880+
881+
override Instruction getResult() { result = this.getInstruction(LoadTag()) }
882+
883+
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
884+
tag = StructuredBindingAccessTag() and
885+
kind instanceof GotoEdge and
886+
result = this.getInstruction(LoadTag())
887+
or
888+
tag = LoadTag() and
889+
kind instanceof GotoEdge and
890+
result = this.getParent().getChildSuccessor(this)
891+
}
892+
893+
override Instruction getChildSuccessor(TranslatedElement child) { none() }
894+
895+
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
896+
tag = StructuredBindingAccessTag() and
897+
opcode instanceof Opcode::VariableAddress and
898+
resultType = getTypeForGLValue(this.getReferenceType())
899+
or
900+
tag = LoadTag() and
901+
opcode instanceof Opcode::Load and
902+
resultType = getTypeForPRValue(this.getReferenceType())
903+
}
904+
905+
private Type getReferenceType() {
906+
result.(ReferenceType).getBaseType() = expr.getUnderlyingType()
907+
}
908+
909+
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
910+
tag = LoadTag() and
911+
operandTag instanceof AddressOperandTag and
912+
result = this.getInstruction(StructuredBindingAccessTag())
913+
}
914+
915+
override IRVariable getInstructionVariable(InstructionTag tag) {
916+
tag = StructuredBindingAccessTag() and
917+
result = getIRUserVariable(expr.getEnclosingFunction(), expr.getTarget())
918+
}
919+
}
920+
863921
class TranslatedFunctionAccess extends TranslatedNonConstantExpr {
864922
override FunctionAccess expr;
865923

cpp/ql/test/library-tests/ir/ir/operand_locations.expected

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6694,16 +6694,22 @@
66946694
| ir.cpp:1466:26:1466:27 | StoreValue | r1466_3 |
66956695
| ir.cpp:1466:26:1466:27 | Unary | r1466_2 |
66966696
| ir.cpp:1467:9:1467:10 | Address | &:r1467_2 |
6697-
| ir.cpp:1467:9:1467:14 | ChiPartial | partial:m1467_3 |
6698-
| ir.cpp:1467:9:1467:14 | ChiTotal | total:m0_14 |
6697+
| ir.cpp:1467:9:1467:10 | Address | &:r1467_3 |
6698+
| ir.cpp:1467:9:1467:10 | Load | m0_14 |
6699+
| ir.cpp:1467:9:1467:14 | ChiPartial | partial:m1467_4 |
6700+
| ir.cpp:1467:9:1467:14 | ChiTotal | total:m1463_12 |
66996701
| ir.cpp:1467:14:1467:14 | StoreValue | r1467_1 |
67006702
| ir.cpp:1468:14:1468:16 | Address | &:r1468_1 |
6701-
| ir.cpp:1468:20:1468:21 | StoreValue | r1468_3 |
6702-
| ir.cpp:1468:20:1468:21 | Unary | r1468_2 |
6703+
| ir.cpp:1468:20:1468:21 | Address | &:r1468_2 |
6704+
| ir.cpp:1468:20:1468:21 | Load | m0_14 |
6705+
| ir.cpp:1468:20:1468:21 | StoreValue | r1468_4 |
6706+
| ir.cpp:1468:20:1468:21 | Unary | r1468_3 |
67036707
| ir.cpp:1469:13:1469:13 | Address | &:r1469_1 |
67046708
| ir.cpp:1469:17:1469:18 | Address | &:r1469_2 |
6705-
| ir.cpp:1469:17:1469:18 | Load | m1467_3 |
6706-
| ir.cpp:1469:17:1469:18 | StoreValue | r1469_3 |
6709+
| ir.cpp:1469:17:1469:18 | Address | &:r1469_3 |
6710+
| ir.cpp:1469:17:1469:18 | Load | m0_14 |
6711+
| ir.cpp:1469:17:1469:18 | Load | m1467_4 |
6712+
| ir.cpp:1469:17:1469:18 | StoreValue | r1469_4 |
67076713
| ir.cpp:1473:15:1473:36 | Address | &:r1473_1 |
67086714
| ir.cpp:1473:40:1473:41 | StoreValue | r1473_3 |
67096715
| ir.cpp:1473:40:1473:41 | Unary | r1473_2 |
@@ -6730,7 +6736,7 @@
67306736
| ir.cpp:1476:9:1476:10 | Load | m1475_9 |
67316737
| ir.cpp:1476:9:1476:10 | Unary | r1476_3 |
67326738
| ir.cpp:1476:9:1476:14 | ChiPartial | partial:m1476_5 |
6733-
| ir.cpp:1476:9:1476:14 | ChiTotal | total:m1463_12 |
6739+
| ir.cpp:1476:9:1476:14 | ChiTotal | total:m1467_5 |
67346740
| ir.cpp:1476:14:1476:14 | StoreValue | r1476_1 |
67356741
| ir.cpp:1477:14:1477:16 | Address | &:r1477_1 |
67366742
| ir.cpp:1477:20:1477:21 | Address | &:r1477_2 |
@@ -6809,35 +6815,53 @@
68096815
| ir.cpp:1503:47:1503:47 | Unary | r1503_34 |
68106816
| ir.cpp:1503:47:1503:47 | Unary | r1503_38 |
68116817
| ir.cpp:1504:9:1504:9 | Address | &:r1504_2 |
6818+
| ir.cpp:1504:9:1504:9 | Address | &:r1504_3 |
6819+
| ir.cpp:1504:9:1504:9 | Load | m1503_12 |
6820+
| ir.cpp:1504:9:1504:15 | ChiPartial | partial:m1504_4 |
6821+
| ir.cpp:1504:9:1504:15 | ChiTotal | total:m1503_4 |
68126822
| ir.cpp:1504:13:1504:15 | StoreValue | r1504_1 |
68136823
| ir.cpp:1505:17:1505:18 | Address | &:r1505_1 |
6814-
| ir.cpp:1505:22:1505:22 | StoreValue | r1505_3 |
6815-
| ir.cpp:1505:22:1505:22 | Unary | r1505_2 |
6824+
| ir.cpp:1505:22:1505:22 | Address | &:r1505_2 |
6825+
| ir.cpp:1505:22:1505:22 | Load | m1503_12 |
6826+
| ir.cpp:1505:22:1505:22 | StoreValue | r1505_4 |
6827+
| ir.cpp:1505:22:1505:22 | Unary | r1505_3 |
68166828
| ir.cpp:1506:13:1506:13 | Address | &:r1506_1 |
68176829
| ir.cpp:1506:17:1506:17 | Address | &:r1506_2 |
6818-
| ir.cpp:1506:17:1506:17 | Load | ~m1503_8 |
6819-
| ir.cpp:1506:17:1506:17 | StoreValue | r1506_3 |
6830+
| ir.cpp:1506:17:1506:17 | Address | &:r1506_3 |
6831+
| ir.cpp:1506:17:1506:17 | Load | m1503_8 |
6832+
| ir.cpp:1506:17:1506:17 | Load | ~m1503_4 |
6833+
| ir.cpp:1506:17:1506:17 | StoreValue | r1506_4 |
68206834
| ir.cpp:1507:9:1507:9 | Address | &:r1507_2 |
6821-
| ir.cpp:1507:9:1507:13 | ChiPartial | partial:m1507_3 |
6822-
| ir.cpp:1507:9:1507:13 | ChiTotal | total:m1503_22 |
6835+
| ir.cpp:1507:9:1507:9 | Address | &:r1507_3 |
6836+
| ir.cpp:1507:9:1507:9 | Load | m1503_22 |
6837+
| ir.cpp:1507:9:1507:13 | ChiPartial | partial:m1507_4 |
6838+
| ir.cpp:1507:9:1507:13 | ChiTotal | total:m1500_6 |
68236839
| ir.cpp:1507:13:1507:13 | StoreValue | r1507_1 |
6824-
| ir.cpp:1508:9:1508:10 | Address | &:r1508_4 |
6825-
| ir.cpp:1508:9:1508:14 | ChiPartial | partial:m1508_5 |
6826-
| ir.cpp:1508:9:1508:14 | ChiTotal | total:m1503_4 |
6840+
| ir.cpp:1508:9:1508:10 | Address | &:r1508_5 |
6841+
| ir.cpp:1508:9:1508:14 | ChiPartial | partial:m1508_6 |
6842+
| ir.cpp:1508:9:1508:14 | ChiTotal | total:m1507_5 |
68276843
| ir.cpp:1508:10:1508:10 | Address | &:r1508_2 |
6844+
| ir.cpp:1508:10:1508:10 | Address | &:r1508_3 |
68286845
| ir.cpp:1508:10:1508:10 | Load | m1503_26 |
6829-
| ir.cpp:1508:10:1508:10 | Unary | r1508_3 |
6846+
| ir.cpp:1508:10:1508:10 | Load | ~m1503_4 |
6847+
| ir.cpp:1508:10:1508:10 | Unary | r1508_4 |
68306848
| ir.cpp:1508:14:1508:14 | StoreValue | r1508_1 |
68316849
| ir.cpp:1509:14:1509:15 | Address | &:r1509_1 |
6832-
| ir.cpp:1509:19:1509:19 | StoreValue | r1509_3 |
6833-
| ir.cpp:1509:19:1509:19 | Unary | r1509_2 |
6850+
| ir.cpp:1509:19:1509:19 | Address | &:r1509_2 |
6851+
| ir.cpp:1509:19:1509:19 | Load | m1503_22 |
6852+
| ir.cpp:1509:19:1509:19 | StoreValue | r1509_4 |
6853+
| ir.cpp:1509:19:1509:19 | Unary | r1509_3 |
68346854
| ir.cpp:1510:14:1510:15 | Address | &:r1510_1 |
6835-
| ir.cpp:1510:19:1510:20 | StoreValue | r1510_3 |
6836-
| ir.cpp:1510:20:1510:20 | Unary | r1510_2 |
6855+
| ir.cpp:1510:19:1510:20 | StoreValue | r1510_4 |
6856+
| ir.cpp:1510:20:1510:20 | Address | &:r1510_2 |
6857+
| ir.cpp:1510:20:1510:20 | Load | m1503_22 |
6858+
| ir.cpp:1510:20:1510:20 | Unary | r1510_3 |
68376859
| ir.cpp:1511:13:1511:13 | Address | &:r1511_1 |
68386860
| ir.cpp:1511:17:1511:17 | Address | &:r1511_2 |
6839-
| ir.cpp:1511:17:1511:17 | Load | m1507_3 |
6840-
| ir.cpp:1511:17:1511:17 | StoreValue | r1511_3 |
6861+
| ir.cpp:1511:17:1511:17 | Address | &:r1511_3 |
6862+
| ir.cpp:1511:17:1511:17 | Load | m1503_22 |
6863+
| ir.cpp:1511:17:1511:17 | Load | ~m1508_7 |
6864+
| ir.cpp:1511:17:1511:17 | StoreValue | r1511_4 |
68416865
| ir.cpp:1515:14:1515:35 | Address | &:r1515_1 |
68426866
| ir.cpp:1515:39:1515:39 | Address | &:r1515_2 |
68436867
| ir.cpp:1515:39:1515:39 | Load | m1500_8 |
@@ -6885,7 +6909,7 @@
68856909
| ir.cpp:1524:9:1524:9 | Load | m1519_7 |
68866910
| ir.cpp:1524:9:1524:9 | Unary | r1524_3 |
68876911
| ir.cpp:1524:9:1524:13 | ChiPartial | partial:m1524_5 |
6888-
| ir.cpp:1524:9:1524:13 | ChiTotal | total:m1500_6 |
6912+
| ir.cpp:1524:9:1524:13 | ChiTotal | total:m1508_7 |
68896913
| ir.cpp:1524:13:1524:13 | StoreValue | r1524_1 |
68906914
| ir.cpp:1525:9:1525:10 | Address | &:r1525_5 |
68916915
| ir.cpp:1525:9:1525:14 | ChiPartial | partial:m1525_6 |

0 commit comments

Comments
 (0)