Skip to content

Commit 4513fd1

Browse files
committed
C++: test for destructors in range-based for
1 parent 820f4a5 commit 4513fd1

File tree

3 files changed

+191
-14
lines changed

3 files changed

+191
-14
lines changed

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

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9384,14 +9384,30 @@ ir.cpp:
93849384
# 1054| getRightOperand().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
93859385
# 1054| Type = [IntType] int
93869386
# 1054| ValueCategory = prvalue(load)
9387+
# 1059| [CopyAssignmentOperator] vector<String>& vector<String>::operator=(vector<String> const&)
9388+
# 1059| <params>:
9389+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
9390+
#-----| Type = [LValueReferenceType] const vector<String> &
93879391
# 1059| [CopyAssignmentOperator] vector<int>& vector<int>::operator=(vector<int> const&)
93889392
# 1059| <params>:
93899393
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
93909394
#-----| Type = [LValueReferenceType] const vector<int> &
9391-
# 1059| [MoveAssignmentOperator] vector<int>& vector<int>::operator=(vector<int>&&)
9395+
# 1059| [CopyConstructor] void vector<String>::vector(vector<String> const&)
9396+
# 1059| <params>:
9397+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
9398+
#-----| Type = [LValueReferenceType] const vector<String> &
9399+
# 1059| [CopyConstructor] void vector<int>::vector(vector<int> const&)
93929400
# 1059| <params>:
93939401
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
9394-
#-----| Type = [RValueReferenceType] vector<int> &&
9402+
#-----| Type = [LValueReferenceType] const vector<int> &
9403+
# 1060| [CopyAssignmentOperator] vector<String>::iterator& vector<String>::iterator::operator=(vector<String>::iterator const public&)
9404+
# 1060| <params>:
9405+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
9406+
#-----| Type = [LValueReferenceType] const iterator &
9407+
# 1060| [MoveAssignmentOperator] vector<String>::iterator& vector<String>::iterator::operator=(vector<String>::iterator&&)
9408+
# 1060| <params>:
9409+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
9410+
#-----| Type = [RValueReferenceType] iterator &&
93959411
# 1060| [CopyAssignmentOperator] vector<int>::iterator& vector<int>::iterator::operator=(vector<int>::iterator const public&)
93969412
# 1060| <params>:
93979413
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
@@ -9400,14 +9416,22 @@ ir.cpp:
94009416
# 1060| <params>:
94019417
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
94029418
#-----| Type = [RValueReferenceType] iterator &&
9419+
# 1062| [MemberFunction] vector<String>::iterator& vector<String>::iterator::operator++()
9420+
# 1062| <params>:
94039421
# 1062| [MemberFunction] vector<T>::iterator& vector<T>::iterator::operator++()
94049422
# 1062| <params>:
94059423
# 1062| [MemberFunction] vector<int>::iterator& vector<int>::iterator::operator++()
94069424
# 1062| <params>:
9425+
# 1063| [ConstMemberFunction] String& vector<String>::iterator::operator*() const
9426+
# 1063| <params>:
94079427
# 1063| [ConstMemberFunction] T& vector<T>::iterator::operator*() const
94089428
# 1063| <params>:
94099429
# 1063| [ConstMemberFunction] int& vector<int>::iterator::operator*() const
94109430
# 1063| <params>:
9431+
# 1065| [ConstMemberFunction] bool vector<String>::iterator::operator!=(vector<String>::iterator) const
9432+
# 1065| <params>:
9433+
# 1065| getParameter(0): [Parameter] right
9434+
# 1065| Type = [NestedStruct] iterator
94119435
# 1065| [ConstMemberFunction] bool vector<T>::iterator::operator!=(vector<T>::iterator) const
94129436
# 1065| <params>:
94139437
# 1065| getParameter(0): [Parameter] right
@@ -9416,10 +9440,24 @@ ir.cpp:
94169440
# 1065| <params>:
94179441
# 1065| getParameter(0): [Parameter] right
94189442
# 1065| Type = [NestedStruct] iterator
9443+
# 1067| [Constructor] void vector<String>::vector(String)
9444+
# 1067| <params>:
9445+
# 1067| getParameter(0): [Parameter] (unnamed parameter 0)
9446+
# 1067| Type = [Struct] String
9447+
# 1067| [Constructor] void vector<T>::vector(T)
9448+
# 1067| <params>:
9449+
# 1067| getParameter(0): [Parameter] (unnamed parameter 0)
9450+
# 1067| Type = [TemplateParameter] T
9451+
# 1067| [Destructor] void vector<T>::~vector()
9452+
# 1067| <params>:
9453+
# 1068| [ConstMemberFunction] vector<String>::iterator vector<String>::begin() const
9454+
# 1068| <params>:
94199455
# 1068| [ConstMemberFunction] vector<T>::iterator vector<T>::begin() const
94209456
# 1068| <params>:
94219457
# 1068| [ConstMemberFunction] vector<int>::iterator vector<int>::begin() const
94229458
# 1068| <params>:
9459+
# 1069| [ConstMemberFunction] vector<String>::iterator vector<String>::end() const
9460+
# 1069| <params>:
94239461
# 1069| [ConstMemberFunction] vector<T>::iterator vector<T>::end() const
94249462
# 1069| <params>:
94259463
# 1069| [ConstMemberFunction] vector<int>::iterator vector<int>::end() const
@@ -16346,7 +16384,47 @@ ir.cpp:
1634616384
# 2145| getQualifier(): [VariableAccess] s
1634716385
# 2145| Type = [Struct] String
1634816386
# 2145| ValueCategory = lvalue
16349-
# 2148| getStmt(2): [ReturnStmt] return ...
16387+
# 2149| getStmt(2): [RangeBasedForStmt] for(...:...) ...
16388+
# 2149| getChild(0): [DeclStmt] declaration
16389+
# 2149| getBeginEndDeclaration(): [DeclStmt] declaration
16390+
# 2149| getCondition(): [FunctionCall] call to operator!=
16391+
# 2149| Type = [BoolType] bool
16392+
# 2149| ValueCategory = prvalue
16393+
# 2149| getQualifier(): [VariableAccess] (__begin)
16394+
# 2149| Type = [NestedStruct] iterator
16395+
# 2149| ValueCategory = lvalue
16396+
# 2149| getArgument(0): [VariableAccess] (__end)
16397+
# 2149| Type = [NestedStruct] iterator
16398+
# 2149| ValueCategory = prvalue(load)
16399+
#-----| getQualifier().getFullyConverted(): [CStyleCast] (const iterator)...
16400+
#-----| Conversion = [GlvalueConversion] glvalue conversion
16401+
#-----| Type = [SpecifiedType] const iterator
16402+
#-----| ValueCategory = lvalue
16403+
# 2149| getUpdate(): [FunctionCall] call to operator++
16404+
# 2149| Type = [LValueReferenceType] iterator &
16405+
# 2149| ValueCategory = prvalue
16406+
# 2149| getQualifier(): [VariableAccess] (__begin)
16407+
# 2149| Type = [NestedStruct] iterator
16408+
# 2149| ValueCategory = lvalue
16409+
# 2149| getChild(4): [DeclStmt] declaration
16410+
# 2149| getStmt(): [BlockStmt] { ... }
16411+
# 2150| getStmt(0): [DeclStmt] declaration
16412+
# 2150| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2
16413+
# 2150| Type = [Struct] String
16414+
# 2150| getVariable().getInitializer(): [Initializer] initializer for s2
16415+
# 2150| getExpr(): [ConstructorCall] call to String
16416+
# 2150| Type = [VoidType] void
16417+
# 2150| ValueCategory = prvalue
16418+
# 2151| getImplicitDestructorCall(0): [DestructorCall] call to ~String
16419+
# 2151| Type = [VoidType] void
16420+
# 2151| ValueCategory = prvalue
16421+
# 2151| getQualifier(): [VariableAccess] s2
16422+
# 2151| Type = [Struct] String
16423+
# 2151| ValueCategory = lvalue
16424+
# 2149| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
16425+
# 2149| Type = [NestedStruct] iterator
16426+
# 2149| ValueCategory = lvalue
16427+
# 2152| getStmt(3): [ReturnStmt] return ...
1635016428
perf-regression.cpp:
1635116429
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
1635216430
# 4| <params>:

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,7 @@ struct vector {
10641064

10651065
bool operator!=(iterator right) const;
10661066
};
1067-
1067+
vector(T); ~vector();
10681068
iterator begin() const;
10691069
iterator end() const;
10701070
};
@@ -2145,6 +2145,12 @@ void ForDestructors() {
21452145
for(String s("hello"); c != 0; c = s.pop_back()) {
21462146
String s2;
21472147
}
2148+
2149+
for(String s : vector<String>(String("hello"))) {
2150+
String s2;
2151+
}
21482152
}
21492153

2154+
2155+
21502156
// semmle-extractor-options: -std=c++17 --clang

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

Lines changed: 103 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12080,16 +12080,109 @@ ir.cpp:
1208012080
#-----| Goto (back edge) -> Block 1
1208112081

1208212082
# 2145| Block 3
12083-
# 2145| r2145_24(glval<String>) = VariableAddress[s] :
12084-
# 2145| r2145_25(glval<unknown>) = FunctionAddress[~String] :
12085-
# 2145| v2145_26(void) = Call[~String] : func:r2145_25, this:r2145_24
12086-
# 2145| mu2145_27(unknown) = ^CallSideEffect : ~m?
12087-
# 2145| v2145_28(void) = ^IndirectReadSideEffect[-1] : &:r2145_24, ~m?
12088-
# 2145| mu2145_29(String) = ^IndirectMayWriteSideEffect[-1] : &:r2145_24
12089-
# 2148| v2148_1(void) = NoOp :
12090-
# 2143| v2143_4(void) = ReturnVoid :
12091-
# 2143| v2143_5(void) = AliasedUse : ~m?
12092-
# 2143| v2143_6(void) = ExitFunction :
12083+
# 2145| r2145_24(glval<String>) = VariableAddress[s] :
12084+
# 2145| r2145_25(glval<unknown>) = FunctionAddress[~String] :
12085+
# 2145| v2145_26(void) = Call[~String] : func:r2145_25, this:r2145_24
12086+
# 2145| mu2145_27(unknown) = ^CallSideEffect : ~m?
12087+
# 2145| v2145_28(void) = ^IndirectReadSideEffect[-1] : &:r2145_24, ~m?
12088+
# 2145| mu2145_29(String) = ^IndirectMayWriteSideEffect[-1] : &:r2145_24
12089+
# 2149| r2149_1(glval<vector<String> &&>) = VariableAddress[(__range)] :
12090+
# 2149| r2149_2(glval<vector<String>>) = VariableAddress[#temp2149:20] :
12091+
# 2149| mu2149_3(vector<String>) = Uninitialized[#temp2149:20] : &:r2149_2
12092+
# 2149| r2149_4(glval<unknown>) = FunctionAddress[vector] :
12093+
# 2149| r2149_5(glval<String>) = VariableAddress[#temp2149:35] :
12094+
# 2149| mu2149_6(String) = Uninitialized[#temp2149:35] : &:r2149_5
12095+
# 2149| r2149_7(glval<unknown>) = FunctionAddress[String] :
12096+
# 2149| r2149_8(glval<char[6]>) = StringConstant["hello"] :
12097+
# 2149| r2149_9(char *) = Convert : r2149_8
12098+
# 2149| v2149_10(void) = Call[String] : func:r2149_7, this:r2149_5, 0:r2149_9
12099+
# 2149| mu2149_11(unknown) = ^CallSideEffect : ~m?
12100+
# 2149| v2149_12(void) = ^BufferReadSideEffect[0] : &:r2149_9, ~m?
12101+
# 2149| mu2149_13(String) = ^IndirectMayWriteSideEffect[-1] : &:r2149_5
12102+
# 2149| r2149_14(String) = Load[#temp2149:35] : &:r2149_5, ~m?
12103+
# 2149| v2149_15(void) = Call[vector] : func:r2149_4, this:r2149_2, 0:r2149_14
12104+
# 2149| mu2149_16(unknown) = ^CallSideEffect : ~m?
12105+
# 2149| mu2149_17(vector<String>) = ^IndirectMayWriteSideEffect[-1] : &:r2149_2
12106+
# 2149| r2149_18(vector<String> &) = CopyValue : r2149_2
12107+
# 2149| mu2149_19(vector<String> &&) = Store[(__range)] : &:r2149_1, r2149_18
12108+
# 2149| r2149_20(glval<iterator>) = VariableAddress[(__begin)] :
12109+
# 2149| r2149_21(glval<vector<String> &&>) = VariableAddress[(__range)] :
12110+
# 2149| r2149_22(vector<String> &&) = Load[(__range)] : &:r2149_21, ~m?
12111+
#-----| r0_1(glval<vector<String>>) = CopyValue : r2149_22
12112+
#-----| r0_2(glval<vector<String>>) = Convert : r0_1
12113+
# 2149| r2149_23(glval<unknown>) = FunctionAddress[begin] :
12114+
# 2149| r2149_24(iterator) = Call[begin] : func:r2149_23, this:r0_2
12115+
# 2149| mu2149_25(unknown) = ^CallSideEffect : ~m?
12116+
#-----| v0_3(void) = ^IndirectReadSideEffect[-1] : &:r0_2, ~m?
12117+
# 2149| mu2149_26(iterator) = Store[(__begin)] : &:r2149_20, r2149_24
12118+
# 2149| r2149_27(glval<iterator>) = VariableAddress[(__end)] :
12119+
# 2149| r2149_28(glval<vector<String> &&>) = VariableAddress[(__range)] :
12120+
# 2149| r2149_29(vector<String> &&) = Load[(__range)] : &:r2149_28, ~m?
12121+
#-----| r0_4(glval<vector<String>>) = CopyValue : r2149_29
12122+
#-----| r0_5(glval<vector<String>>) = Convert : r0_4
12123+
# 2149| r2149_30(glval<unknown>) = FunctionAddress[end] :
12124+
# 2149| r2149_31(iterator) = Call[end] : func:r2149_30, this:r0_5
12125+
# 2149| mu2149_32(unknown) = ^CallSideEffect : ~m?
12126+
#-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m?
12127+
# 2149| mu2149_33(iterator) = Store[(__end)] : &:r2149_27, r2149_31
12128+
#-----| Goto -> Block 4
12129+
12130+
# 2149| Block 4
12131+
# 2149| r2149_34(glval<iterator>) = VariableAddress[(__begin)] :
12132+
#-----| r0_7(glval<iterator>) = Convert : r2149_34
12133+
# 2149| r2149_35(glval<unknown>) = FunctionAddress[operator!=] :
12134+
# 2149| r2149_36(glval<iterator>) = VariableAddress[(__end)] :
12135+
# 2149| r2149_37(iterator) = Load[(__end)] : &:r2149_36, ~m?
12136+
# 2149| r2149_38(bool) = Call[operator!=] : func:r2149_35, this:r0_7, 0:r2149_37
12137+
# 2149| mu2149_39(unknown) = ^CallSideEffect : ~m?
12138+
#-----| v0_8(void) = ^IndirectReadSideEffect[-1] : &:r0_7, ~m?
12139+
# 2149| v2149_40(void) = ConditionalBranch : r2149_38
12140+
#-----| False -> Block 6
12141+
#-----| True -> Block 5
12142+
12143+
# 2149| Block 5
12144+
# 2149| r2149_41(glval<String>) = VariableAddress[s] :
12145+
# 2149| mu2149_42(String) = Uninitialized[s] : &:r2149_41
12146+
# 2149| r2149_43(glval<unknown>) = FunctionAddress[String] :
12147+
# 2149| r2149_44(glval<iterator>) = VariableAddress[(__begin)] :
12148+
#-----| r0_9(glval<iterator>) = Convert : r2149_44
12149+
# 2149| r2149_45(glval<unknown>) = FunctionAddress[operator*] :
12150+
# 2149| r2149_46(String &) = Call[operator*] : func:r2149_45, this:r0_9
12151+
# 2149| mu2149_47(unknown) = ^CallSideEffect : ~m?
12152+
#-----| v0_10(void) = ^IndirectReadSideEffect[-1] : &:r0_9, ~m?
12153+
# 2149| r2149_48(glval<String>) = CopyValue : r2149_46
12154+
# 2149| r2149_49(glval<String>) = Convert : r2149_48
12155+
# 2149| r2149_50(String &) = CopyValue : r2149_49
12156+
# 2149| v2149_51(void) = Call[String] : func:r2149_43, this:r2149_41, 0:r2149_50
12157+
# 2149| mu2149_52(unknown) = ^CallSideEffect : ~m?
12158+
# 2149| v2149_53(void) = ^BufferReadSideEffect[0] : &:r2149_50, ~m?
12159+
# 2149| mu2149_54(String) = ^IndirectMayWriteSideEffect[-1] : &:r2149_41
12160+
# 2150| r2150_1(glval<String>) = VariableAddress[s2] :
12161+
# 2150| mu2150_2(String) = Uninitialized[s2] : &:r2150_1
12162+
# 2150| r2150_3(glval<unknown>) = FunctionAddress[String] :
12163+
# 2150| v2150_4(void) = Call[String] : func:r2150_3, this:r2150_1
12164+
# 2150| mu2150_5(unknown) = ^CallSideEffect : ~m?
12165+
# 2150| mu2150_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2150_1
12166+
# 2151| r2151_1(glval<String>) = VariableAddress[s2] :
12167+
# 2151| r2151_2(glval<unknown>) = FunctionAddress[~String] :
12168+
# 2151| v2151_3(void) = Call[~String] : func:r2151_2, this:r2151_1
12169+
# 2151| mu2151_4(unknown) = ^CallSideEffect : ~m?
12170+
# 2151| v2151_5(void) = ^IndirectReadSideEffect[-1] : &:r2151_1, ~m?
12171+
# 2151| mu2151_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2151_1
12172+
# 2149| r2149_55(glval<iterator>) = VariableAddress[(__begin)] :
12173+
# 2149| r2149_56(glval<unknown>) = FunctionAddress[operator++] :
12174+
# 2149| r2149_57(iterator &) = Call[operator++] : func:r2149_56, this:r2149_55
12175+
# 2149| mu2149_58(unknown) = ^CallSideEffect : ~m?
12176+
# 2149| v2149_59(void) = ^IndirectReadSideEffect[-1] : &:r2149_55, ~m?
12177+
# 2149| mu2149_60(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2149_55
12178+
# 2149| r2149_61(glval<iterator>) = CopyValue : r2149_57
12179+
#-----| Goto (back edge) -> Block 4
12180+
12181+
# 2152| Block 6
12182+
# 2152| v2152_1(void) = NoOp :
12183+
# 2143| v2143_4(void) = ReturnVoid :
12184+
# 2143| v2143_5(void) = AliasedUse : ~m?
12185+
# 2143| v2143_6(void) = ExitFunction :
1209312186

1209412187
perf-regression.cpp:
1209512188
# 6| void Big::Big()

0 commit comments

Comments
 (0)