Skip to content

Commit 337db6b

Browse files
authored
Merge pull request #15609 from jketema/destructors3
C++: Output the declaration entries used in range-based for-loops
2 parents 2172c48 + c79cc49 commit 337db6b

File tree

5 files changed

+207
-10
lines changed

5 files changed

+207
-10
lines changed

cpp/ql/lib/semmle/code/cpp/PrintAST.qll

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,11 @@ private predicate namedExprChildPredicates(Expr expr, Element ele, string pred)
835835
or
836836
expr.(OverloadedArrayExpr).getArrayOffset() = ele and pred = "getArrayOffset()"
837837
or
838-
expr.(OverloadedPointerDereferenceExpr).getExpr() = ele and pred = "getExpr()"
838+
// OverloadedPointerDereferenceExpr::getExpr/0 also considers qualifiers, which are already handled above for all Call classes.
839+
not expr.(OverloadedPointerDereferenceExpr).getQualifier() =
840+
expr.(OverloadedPointerDereferenceExpr).getExpr() and
841+
expr.(OverloadedPointerDereferenceExpr).getExpr() = ele and
842+
pred = "getExpr()"
839843
or
840844
expr.(CommaExpr).getLeftOperand() = ele and pred = "getLeftOperand()"
841845
or

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,6 @@ private module IRDeclarationEntries {
474474
* This class exists to work around the fact that `DeclStmt`s in some cases
475475
* do not have `DeclarationEntry`s. Currently, this is the case for:
476476
* - `DeclStmt`s in template instantiations.
477-
* - `DeclStmt`s that are generated by the desugaring of range-based for-loops.
478477
*
479478
* So instead, the IR works with `IRDeclarationEntry`s that synthesize missing
480479
* `DeclarationEntry`s when there is no result for `DeclStmt::getDeclarationEntry`.

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

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9479,7 +9479,43 @@ ir.cpp:
94799479
# 1079| getEntryPoint(): [BlockStmt] { ... }
94809480
# 1080| getStmt(0): [RangeBasedForStmt] for(...:...) ...
94819481
# 1080| getChild(0): [DeclStmt] declaration
9482+
# 1080| getDeclarationEntry(0): (no string representation)
9483+
# 1080| Type = [LValueReferenceType] const vector<int> &
9484+
#-----| getVariable().getInitializer(): [Initializer] initializer for (__range)
9485+
# 1080| getExpr(): [VariableAccess] v
9486+
# 1080| Type = [LValueReferenceType] const vector<int> &
9487+
# 1080| ValueCategory = prvalue(load)
9488+
# 1080| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
9489+
# 1080| Type = [LValueReferenceType] const vector<int> &
9490+
# 1080| ValueCategory = prvalue
9491+
# 1080| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
9492+
# 1080| Type = [SpecifiedType] const vector<int>
9493+
# 1080| ValueCategory = lvalue
94829494
# 1080| getBeginEndDeclaration(): [DeclStmt] declaration
9495+
# 1080| getDeclarationEntry(0): (no string representation)
9496+
# 1080| Type = [NestedStruct] iterator
9497+
#-----| getVariable().getInitializer(): [Initializer] initializer for (__begin)
9498+
# 1080| getExpr(): [FunctionCall] call to begin
9499+
# 1080| Type = [NestedStruct] iterator
9500+
# 1080| ValueCategory = prvalue
9501+
# 1080| getQualifier(): [VariableAccess] (__range)
9502+
# 1080| Type = [LValueReferenceType] const vector<int> &
9503+
# 1080| ValueCategory = prvalue(load)
9504+
#-----| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
9505+
#-----| Type = [SpecifiedType] const vector<int>
9506+
#-----| ValueCategory = lvalue
9507+
# 1080| getDeclarationEntry(1): (no string representation)
9508+
# 1080| Type = [NestedStruct] iterator
9509+
#-----| getVariable().getInitializer(): [Initializer] initializer for (__end)
9510+
# 1080| getExpr(): [FunctionCall] call to end
9511+
# 1080| Type = [NestedStruct] iterator
9512+
# 1080| ValueCategory = prvalue
9513+
# 1080| getQualifier(): [VariableAccess] (__range)
9514+
# 1080| Type = [LValueReferenceType] const vector<int> &
9515+
# 1080| ValueCategory = prvalue(load)
9516+
#-----| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
9517+
#-----| Type = [SpecifiedType] const vector<int>
9518+
#-----| ValueCategory = lvalue
94839519
# 1080| getCondition(): [FunctionCall] call to operator!=
94849520
# 1080| Type = [BoolType] bool
94859521
# 1080| ValueCategory = prvalue
@@ -9500,6 +9536,22 @@ ir.cpp:
95009536
# 1080| Type = [NestedStruct] iterator
95019537
# 1080| ValueCategory = lvalue
95029538
# 1080| getChild(4): [DeclStmt] declaration
9539+
# 1080| getDeclarationEntry(0): [VariableDeclarationEntry] definition of e
9540+
# 1080| Type = [IntType] int
9541+
# 1080| getVariable().getInitializer(): [Initializer] initializer for e
9542+
# 1080| getExpr(): [OverloadedPointerDereferenceExpr] call to operator*
9543+
# 1080| Type = [LValueReferenceType] int &
9544+
# 1080| ValueCategory = prvalue
9545+
# 1080| getQualifier(): [VariableAccess] (__begin)
9546+
# 1080| Type = [NestedStruct] iterator
9547+
# 1080| ValueCategory = lvalue
9548+
#-----| getQualifier().getFullyConverted(): [CStyleCast] (const iterator)...
9549+
#-----| Conversion = [GlvalueConversion] glvalue conversion
9550+
#-----| Type = [SpecifiedType] const iterator
9551+
#-----| ValueCategory = lvalue
9552+
# 1080| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
9553+
# 1080| Type = [IntType] int
9554+
# 1080| ValueCategory = prvalue(load)
95039555
# 1080| getStmt(): [BlockStmt] { ... }
95049556
# 1081| getStmt(0): [IfStmt] if (...) ...
95059557
# 1081| getCondition(): [GTExpr] ... > ...
@@ -9520,7 +9572,43 @@ ir.cpp:
95209572
# 1080| ValueCategory = lvalue
95219573
# 1086| getStmt(1): [RangeBasedForStmt] for(...:...) ...
95229574
# 1086| getChild(0): [DeclStmt] declaration
9575+
# 1086| getDeclarationEntry(0): (no string representation)
9576+
# 1086| Type = [LValueReferenceType] const vector<int> &
9577+
#-----| getVariable().getInitializer(): [Initializer] initializer for (__range)
9578+
# 1086| getExpr(): [VariableAccess] v
9579+
# 1086| Type = [LValueReferenceType] const vector<int> &
9580+
# 1086| ValueCategory = prvalue(load)
9581+
# 1086| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
9582+
# 1086| Type = [LValueReferenceType] const vector<int> &
9583+
# 1086| ValueCategory = prvalue
9584+
# 1086| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
9585+
# 1086| Type = [SpecifiedType] const vector<int>
9586+
# 1086| ValueCategory = lvalue
95239587
# 1086| getBeginEndDeclaration(): [DeclStmt] declaration
9588+
# 1086| getDeclarationEntry(0): (no string representation)
9589+
# 1086| Type = [NestedStruct] iterator
9590+
#-----| getVariable().getInitializer(): [Initializer] initializer for (__begin)
9591+
# 1086| getExpr(): [FunctionCall] call to begin
9592+
# 1086| Type = [NestedStruct] iterator
9593+
# 1086| ValueCategory = prvalue
9594+
# 1086| getQualifier(): [VariableAccess] (__range)
9595+
# 1086| Type = [LValueReferenceType] const vector<int> &
9596+
# 1086| ValueCategory = prvalue(load)
9597+
#-----| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
9598+
#-----| Type = [SpecifiedType] const vector<int>
9599+
#-----| ValueCategory = lvalue
9600+
# 1086| getDeclarationEntry(1): (no string representation)
9601+
# 1086| Type = [NestedStruct] iterator
9602+
#-----| getVariable().getInitializer(): [Initializer] initializer for (__end)
9603+
# 1086| getExpr(): [FunctionCall] call to end
9604+
# 1086| Type = [NestedStruct] iterator
9605+
# 1086| ValueCategory = prvalue
9606+
# 1086| getQualifier(): [VariableAccess] (__range)
9607+
# 1086| Type = [LValueReferenceType] const vector<int> &
9608+
# 1086| ValueCategory = prvalue(load)
9609+
#-----| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
9610+
#-----| Type = [SpecifiedType] const vector<int>
9611+
#-----| ValueCategory = lvalue
95249612
# 1086| getCondition(): [FunctionCall] call to operator!=
95259613
# 1086| Type = [BoolType] bool
95269614
# 1086| ValueCategory = prvalue
@@ -9541,6 +9629,29 @@ ir.cpp:
95419629
# 1086| Type = [NestedStruct] iterator
95429630
# 1086| ValueCategory = lvalue
95439631
# 1086| getChild(4): [DeclStmt] declaration
9632+
# 1086| getDeclarationEntry(0): [VariableDeclarationEntry] definition of e
9633+
# 1086| Type = [LValueReferenceType] const int &
9634+
# 1086| getVariable().getInitializer(): [Initializer] initializer for e
9635+
# 1086| getExpr(): [OverloadedPointerDereferenceExpr] call to operator*
9636+
# 1086| Type = [LValueReferenceType] int &
9637+
# 1086| ValueCategory = prvalue
9638+
# 1086| getQualifier(): [VariableAccess] (__begin)
9639+
# 1086| Type = [NestedStruct] iterator
9640+
# 1086| ValueCategory = lvalue
9641+
#-----| getQualifier().getFullyConverted(): [CStyleCast] (const iterator)...
9642+
#-----| Conversion = [GlvalueConversion] glvalue conversion
9643+
#-----| Type = [SpecifiedType] const iterator
9644+
#-----| ValueCategory = lvalue
9645+
# 1086| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
9646+
# 1086| Type = [LValueReferenceType] const int &
9647+
# 1086| ValueCategory = prvalue
9648+
# 1086| getExpr(): [CStyleCast] (const int)...
9649+
# 1086| Conversion = [GlvalueConversion] glvalue conversion
9650+
# 1086| Type = [SpecifiedType] const int
9651+
# 1086| ValueCategory = lvalue
9652+
# 1086| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
9653+
# 1086| Type = [IntType] int
9654+
# 1086| ValueCategory = lvalue
95449655
# 1086| getStmt(): [BlockStmt] { ... }
95459656
# 1087| getStmt(0): [IfStmt] if (...) ...
95469657
# 1087| getCondition(): [LTExpr] ... < ...
@@ -16410,7 +16521,48 @@ ir.cpp:
1641016521
# 2152| ValueCategory = prvalue
1641116522
# 2153| getStmt(5): [RangeBasedForStmt] for(...:...) ...
1641216523
# 2153| getChild(0): [DeclStmt] declaration
16524+
# 2153| getDeclarationEntry(0): (no string representation)
16525+
# 2153| Type = [LValueReferenceType] vector<ClassWithDestructor> &
16526+
#-----| getVariable().getInitializer(): [Initializer] initializer for (__range)
16527+
# 2153| getExpr(): [VariableAccess] ys
16528+
# 2153| Type = [ClassTemplateInstantiation,Struct] vector<ClassWithDestructor>
16529+
# 2153| ValueCategory = lvalue
16530+
# 2153| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
16531+
# 2153| Type = [LValueReferenceType] vector<ClassWithDestructor> &
16532+
# 2153| ValueCategory = prvalue
1641316533
# 2153| getBeginEndDeclaration(): [DeclStmt] declaration
16534+
# 2153| getDeclarationEntry(0): (no string representation)
16535+
# 2153| Type = [NestedStruct] iterator
16536+
#-----| getVariable().getInitializer(): [Initializer] initializer for (__begin)
16537+
# 2153| getExpr(): [FunctionCall] call to begin
16538+
# 2153| Type = [NestedStruct] iterator
16539+
# 2153| ValueCategory = prvalue
16540+
# 2153| getQualifier(): [VariableAccess] (__range)
16541+
# 2153| Type = [LValueReferenceType] vector<ClassWithDestructor> &
16542+
# 2153| ValueCategory = prvalue(load)
16543+
#-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector<ClassWithDestructor>)...
16544+
#-----| Conversion = [GlvalueConversion] glvalue conversion
16545+
#-----| Type = [SpecifiedType] const vector<ClassWithDestructor>
16546+
#-----| ValueCategory = lvalue
16547+
#-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
16548+
#-----| Type = [ClassTemplateInstantiation,Struct] vector<ClassWithDestructor>
16549+
#-----| ValueCategory = lvalue
16550+
# 2153| getDeclarationEntry(1): (no string representation)
16551+
# 2153| Type = [NestedStruct] iterator
16552+
#-----| getVariable().getInitializer(): [Initializer] initializer for (__end)
16553+
# 2153| getExpr(): [FunctionCall] call to end
16554+
# 2153| Type = [NestedStruct] iterator
16555+
# 2153| ValueCategory = prvalue
16556+
# 2153| getQualifier(): [VariableAccess] (__range)
16557+
# 2153| Type = [LValueReferenceType] vector<ClassWithDestructor> &
16558+
# 2153| ValueCategory = prvalue(load)
16559+
#-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector<ClassWithDestructor>)...
16560+
#-----| Conversion = [GlvalueConversion] glvalue conversion
16561+
#-----| Type = [SpecifiedType] const vector<ClassWithDestructor>
16562+
#-----| ValueCategory = lvalue
16563+
#-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
16564+
#-----| Type = [ClassTemplateInstantiation,Struct] vector<ClassWithDestructor>
16565+
#-----| ValueCategory = lvalue
1641416566
# 2153| getCondition(): [FunctionCall] call to operator!=
1641516567
# 2153| Type = [BoolType] bool
1641616568
# 2153| ValueCategory = prvalue
@@ -16431,6 +16583,22 @@ ir.cpp:
1643116583
# 2153| Type = [NestedStruct] iterator
1643216584
# 2153| ValueCategory = lvalue
1643316585
# 2153| getChild(4): [DeclStmt] declaration
16586+
# 2153| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y
16587+
# 2153| Type = [Class] ClassWithDestructor
16588+
# 2153| getVariable().getInitializer(): [Initializer] initializer for y
16589+
# 2153| getExpr(): [OverloadedPointerDereferenceExpr] call to operator*
16590+
# 2153| Type = [LValueReferenceType] ClassWithDestructor &
16591+
# 2153| ValueCategory = prvalue
16592+
# 2153| getQualifier(): [VariableAccess] (__begin)
16593+
# 2153| Type = [NestedStruct] iterator
16594+
# 2153| ValueCategory = lvalue
16595+
#-----| getQualifier().getFullyConverted(): [CStyleCast] (const iterator)...
16596+
#-----| Conversion = [GlvalueConversion] glvalue conversion
16597+
#-----| Type = [SpecifiedType] const iterator
16598+
#-----| ValueCategory = lvalue
16599+
# 2153| getExpr().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
16600+
# 2153| Type = [Class] ClassWithDestructor
16601+
# 2153| ValueCategory = prvalue(load)
1643416602
# 2154| getStmt(): [ExprStmt] ExprStmt
1643516603
# 2154| getExpr(): [FunctionCall] call to set_x
1643616604
# 2154| Type = [VoidType] void

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5540,10 +5540,10 @@
55405540
| ir.cpp:1079:39:1079:39 | Address | &:r1079_7 |
55415541
| ir.cpp:1079:39:1079:39 | Load | m1079_6 |
55425542
| ir.cpp:1079:39:1079:39 | SideEffect | m1079_8 |
5543-
| ir.cpp:1080:5:1084:5 | Address | &:r1080_1 |
5544-
| ir.cpp:1080:5:1084:5 | Address | &:r1080_7 |
5545-
| ir.cpp:1080:5:1084:5 | Address | &:r1080_15 |
5546-
| ir.cpp:1080:5:1084:5 | Address | &:r1080_33 |
5543+
| ir.cpp:1080:5:1080:5 | Address | &:r1080_1 |
5544+
| ir.cpp:1080:5:1080:5 | Address | &:r1080_7 |
5545+
| ir.cpp:1080:5:1080:5 | Address | &:r1080_15 |
5546+
| ir.cpp:1080:14:1080:14 | Address | &:r1080_33 |
55475547
| ir.cpp:1080:18:1080:18 | Address | &:r1080_2 |
55485548
| ir.cpp:1080:18:1080:18 | Address | &:r1080_8 |
55495549
| ir.cpp:1080:18:1080:18 | Address | &:r1080_16 |
@@ -5606,10 +5606,10 @@
56065606
| ir.cpp:1081:13:1081:13 | Load | m1080_40 |
56075607
| ir.cpp:1081:13:1081:17 | Condition | r1081_4 |
56085608
| ir.cpp:1081:17:1081:17 | Right | r1081_3 |
5609-
| ir.cpp:1086:5:1090:5 | Address | &:r1086_1 |
5610-
| ir.cpp:1086:5:1090:5 | Address | &:r1086_7 |
5611-
| ir.cpp:1086:5:1090:5 | Address | &:r1086_15 |
5612-
| ir.cpp:1086:5:1090:5 | Address | &:r1086_42 |
5609+
| ir.cpp:1086:5:1086:5 | Address | &:r1086_1 |
5610+
| ir.cpp:1086:5:1086:5 | Address | &:r1086_7 |
5611+
| ir.cpp:1086:5:1086:5 | Address | &:r1086_15 |
5612+
| ir.cpp:1086:21:1086:21 | Address | &:r1086_42 |
56135613
| ir.cpp:1086:25:1086:25 | Address | &:r1086_2 |
56145614
| ir.cpp:1086:25:1086:25 | Address | &:r1086_8 |
56155615
| ir.cpp:1086:25:1086:25 | Address | &:r1086_16 |

cpp/ql/test/library-tests/syntax-zoo/dataflow-ir-consistency.expected

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,37 @@ uniqueNodeLocation
55
missingLocation
66
uniqueNodeToString
77
| builtin.c:5:5:5:11 | (no string representation) | Node should have one toString but has 0. |
8+
| cpp11.cpp:6:5:6:5 | (no string representation) | Node should have one toString but has 0. |
9+
| cpp11.cpp:6:5:6:5 | (no string representation) | Node should have one toString but has 0. |
10+
| cpp11.cpp:6:5:6:5 | (no string representation) | Node should have one toString but has 0. |
11+
| cpp11.cpp:6:5:6:5 | (no string representation) | Node should have one toString but has 0. |
12+
| cpp11.cpp:6:5:6:5 | (no string representation) | Node should have one toString but has 0. |
13+
| cpp11.cpp:6:5:6:5 | (no string representation) | Node should have one toString but has 0. |
14+
| cpp11.cpp:6:5:6:5 | (no string representation) | Node should have one toString but has 0. |
15+
| cpp11.cpp:6:5:6:5 | (no string representation) | Node should have one toString but has 0. |
16+
| cpp11.cpp:6:5:6:5 | (no string representation) | Node should have one toString but has 0. |
17+
| cpp11.cpp:6:5:6:5 | (no string representation) | Node should have one toString but has 0. |
18+
| cpp11.cpp:28:5:28:5 | (no string representation) | Node should have one toString but has 0. |
19+
| cpp11.cpp:28:5:28:5 | (no string representation) | Node should have one toString but has 0. |
20+
| cpp11.cpp:28:5:28:5 | (no string representation) | Node should have one toString but has 0. |
21+
| cpp11.cpp:28:5:28:5 | (no string representation) | Node should have one toString but has 0. |
22+
| cpp11.cpp:28:5:28:5 | (no string representation) | Node should have one toString but has 0. |
23+
| cpp11.cpp:28:5:28:5 | (no string representation) | Node should have one toString but has 0. |
24+
| cpp11.cpp:28:5:28:5 | (no string representation) | Node should have one toString but has 0. |
825
| misc.c:227:7:227:28 | (no string representation) | Node should have one toString but has 0. |
926
| static_init_templates.cpp:80:18:80:23 | (no string representation) | Node should have one toString but has 0. |
1027
| static_init_templates.cpp:80:18:80:23 | (no string representation) | Node should have one toString but has 0. |
1128
| static_init_templates.cpp:89:18:89:23 | (no string representation) | Node should have one toString but has 0. |
1229
| static_init_templates.cpp:89:18:89:23 | (no string representation) | Node should have one toString but has 0. |
30+
| stream_it.cpp:11:3:11:3 | (no string representation) | Node should have one toString but has 0. |
31+
| stream_it.cpp:11:3:11:3 | (no string representation) | Node should have one toString but has 0. |
32+
| stream_it.cpp:11:3:11:3 | (no string representation) | Node should have one toString but has 0. |
33+
| stream_it.cpp:11:3:11:3 | (no string representation) | Node should have one toString but has 0. |
34+
| stream_it.cpp:11:3:11:3 | (no string representation) | Node should have one toString but has 0. |
35+
| stream_it.cpp:11:3:11:3 | (no string representation) | Node should have one toString but has 0. |
36+
| stream_it.cpp:11:3:11:3 | (no string representation) | Node should have one toString but has 0. |
37+
| stream_it.cpp:11:3:11:3 | (no string representation) | Node should have one toString but has 0. |
38+
| stream_it.cpp:11:3:11:3 | (no string representation) | Node should have one toString but has 0. |
1339
parameterCallable
1440
localFlowIsLocal
1541
readStepIsLocal

0 commit comments

Comments
 (0)