Skip to content

Commit 8be02b1

Browse files
committed
C++: Add IR tests exposing incorrect translation due to unhandled bitwise copy
These tests are in addition to exisiting tests involving default copy constructors, which suffer from the same problem, i.e., the extractor not handling bitwise copies.
1 parent b45f56a commit 8be02b1

9 files changed

+528
-0
lines changed

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

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12820,6 +12820,221 @@ ir.cpp:
1282012820
# 1668| Type = [IntType] int
1282112821
# 1668| ValueCategory = prvalue(load)
1282212822
# 1670| getStmt(3): [ReturnStmt] return ...
12823+
# 1672| [TopLevelFunction] void array_structured_binding_non_ref_init()
12824+
# 1672| <params>:
12825+
# 1672| getEntryPoint(): [BlockStmt] { ... }
12826+
# 1673| getStmt(0): [DeclStmt] declaration
12827+
# 1673| getDeclarationEntry(0): [VariableDeclarationEntry] definition of xs
12828+
# 1673| Type = [ArrayType] int[2]
12829+
# 1673| getVariable().getInitializer(): [Initializer] initializer for xs
12830+
# 1673| getExpr(): [ArrayAggregateLiteral] {...}
12831+
# 1673| Type = [ArrayType] int[2]
12832+
# 1673| ValueCategory = prvalue
12833+
# 1673| getElementExpr(0): [Literal] 1
12834+
# 1673| Type = [IntType] int
12835+
# 1673| Value = [Literal] 1
12836+
# 1673| ValueCategory = prvalue
12837+
# 1673| getElementExpr(1): [Literal] 2
12838+
# 1673| Type = [IntType] int
12839+
# 1673| Value = [Literal] 2
12840+
# 1673| ValueCategory = prvalue
12841+
# 1674| getStmt(1): [DeclStmt] declaration
12842+
# 1674| getDeclarationEntry(0): (no string representation)
12843+
# 1674| Type = [ArrayType] int[2]
12844+
# 1674| getVariable().getInitializer(): [Initializer] initializer for (unnamed local variable)
12845+
# 1674| getExpr(): (no string representation)
12846+
# 1674| Type = [ArrayType] int[2]
12847+
# 1674| ValueCategory = prvalue
12848+
# 1674| getDeclarationEntry(1): [VariableDeclarationEntry] definition of x0
12849+
# 1674| Type = [IntType] int
12850+
#-----| getVariable().getInitializer(): [Initializer] initializer for x0
12851+
#-----| getExpr(): [ArrayExpr] access to array
12852+
#-----| Type = [IntType] int
12853+
#-----| ValueCategory = lvalue
12854+
#-----| getArrayBase(): [VariableAccess] (unnamed local variable)
12855+
#-----| Type = [ArrayType] int[2]
12856+
#-----| ValueCategory = lvalue
12857+
#-----| getArrayOffset(): [Literal] 0
12858+
#-----| Type = [LongType] unsigned long
12859+
#-----| Value = [Literal] 0
12860+
#-----| ValueCategory = prvalue
12861+
#-----| getArrayBase().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
12862+
#-----| Type = [IntPointerType] int *
12863+
#-----| ValueCategory = prvalue
12864+
# 1674| getDeclarationEntry(2): [VariableDeclarationEntry] definition of x1
12865+
# 1674| Type = [IntType] int
12866+
#-----| getVariable().getInitializer(): [Initializer] initializer for x1
12867+
#-----| getExpr(): [ArrayExpr] access to array
12868+
#-----| Type = [IntType] int
12869+
#-----| ValueCategory = lvalue
12870+
#-----| getArrayBase(): [VariableAccess] (unnamed local variable)
12871+
#-----| Type = [ArrayType] int[2]
12872+
#-----| ValueCategory = lvalue
12873+
#-----| getArrayOffset(): [Literal] 1
12874+
#-----| Type = [LongType] unsigned long
12875+
#-----| Value = [Literal] 1
12876+
#-----| ValueCategory = prvalue
12877+
#-----| getArrayBase().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
12878+
#-----| Type = [IntPointerType] int *
12879+
#-----| ValueCategory = prvalue
12880+
# 1675| getStmt(2): [ReturnStmt] return ...
12881+
# 1677| [CopyAssignmentOperator] CapturedLambdaMyObj& CapturedLambdaMyObj::operator=(CapturedLambdaMyObj const&)
12882+
# 1677| <params>:
12883+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
12884+
#-----| Type = [LValueReferenceType] const CapturedLambdaMyObj &
12885+
# 1677| [MoveAssignmentOperator] CapturedLambdaMyObj& CapturedLambdaMyObj::operator=(CapturedLambdaMyObj&&)
12886+
# 1677| <params>:
12887+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
12888+
#-----| Type = [RValueReferenceType] CapturedLambdaMyObj &&
12889+
# 1677| [CopyConstructor] void CapturedLambdaMyObj::CapturedLambdaMyObj(CapturedLambdaMyObj const&)
12890+
# 1677| <params>:
12891+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
12892+
#-----| Type = [LValueReferenceType] const CapturedLambdaMyObj &
12893+
# 1677| [MoveConstructor] void CapturedLambdaMyObj::CapturedLambdaMyObj(CapturedLambdaMyObj&&)
12894+
# 1677| <params>:
12895+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
12896+
#-----| Type = [RValueReferenceType] CapturedLambdaMyObj &&
12897+
# 1680| [Constructor] void CapturedLambdaMyObj::CapturedLambdaMyObj()
12898+
# 1680| <params>:
12899+
# 1680| <initializations>:
12900+
# 1680| getEntryPoint(): [BlockStmt] { ... }
12901+
# 1680| getStmt(0): [ReturnStmt] return ...
12902+
# 1683| [TopLevelFunction] void captured_lambda(int, int&, int&&)
12903+
# 1683| <params>:
12904+
# 1683| getParameter(0): [Parameter] x
12905+
# 1683| Type = [IntType] int
12906+
# 1683| getParameter(1): [Parameter] y
12907+
# 1683| Type = [LValueReferenceType] int &
12908+
# 1683| getParameter(2): [Parameter] z
12909+
# 1683| Type = [RValueReferenceType] int &&
12910+
# 1684| getEntryPoint(): [BlockStmt] { ... }
12911+
# 1685| getStmt(0): [DeclStmt] declaration
12912+
# 1685| getDeclarationEntry(0): [VariableDeclarationEntry] definition of obj1
12913+
# 1685| Type = [LValueReferenceType] const CapturedLambdaMyObj &
12914+
# 1685| getVariable().getInitializer(): [Initializer] initializer for obj1
12915+
# 1685| getExpr(): [ConstructorCall] call to CapturedLambdaMyObj
12916+
# 1685| Type = [VoidType] void
12917+
# 1685| ValueCategory = prvalue
12918+
# 1685| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
12919+
# 1685| Type = [LValueReferenceType] const CapturedLambdaMyObj &
12920+
# 1685| ValueCategory = prvalue
12921+
# 1685| getExpr(): [CStyleCast] (const CapturedLambdaMyObj)...
12922+
# 1685| Conversion = [GlvalueConversion] glvalue conversion
12923+
# 1685| Type = [SpecifiedType] const CapturedLambdaMyObj
12924+
# 1685| ValueCategory = lvalue
12925+
# 1685| getExpr(): [TemporaryObjectExpr] temporary object
12926+
# 1685| Type = [Class] CapturedLambdaMyObj
12927+
# 1685| ValueCategory = lvalue
12928+
# 1686| getStmt(1): [DeclStmt] declaration
12929+
# 1686| getDeclarationEntry(0): [VariableDeclarationEntry] definition of obj2
12930+
# 1686| Type = [Class] CapturedLambdaMyObj
12931+
# 1686| getVariable().getInitializer(): [Initializer] initializer for obj2
12932+
# 1686| getExpr(): [ConstructorCall] call to CapturedLambdaMyObj
12933+
# 1686| Type = [VoidType] void
12934+
# 1686| ValueCategory = prvalue
12935+
# 1688| getStmt(2): [DeclStmt] declaration
12936+
# 1688| getDeclarationEntry(0): [VariableDeclarationEntry] definition of lambda_outer
12937+
# 1688| Type = [Closure,LocalClass] decltype([...](...){...})
12938+
# 1688| getVariable().getInitializer(): [Initializer] initializer for lambda_outer
12939+
# 1688| getExpr(): [LambdaExpression] [...](...){...}
12940+
# 1688| Type = [Closure,LocalClass] decltype([...](...){...})
12941+
# 1688| ValueCategory = prvalue
12942+
# 1688| getInitializer(): [ClassAggregateLiteral] {...}
12943+
# 1688| Type = [Closure,LocalClass] decltype([...](...){...})
12944+
# 1688| ValueCategory = prvalue
12945+
# 1688| getFieldExpr(obj1): [Literal] Unknown literal
12946+
# 1688| Type = [SpecifiedType] const CapturedLambdaMyObj
12947+
# 1688| ValueCategory = prvalue
12948+
# 1688| getFieldExpr(obj2): [Literal] Unknown literal
12949+
# 1688| Type = [Class] CapturedLambdaMyObj
12950+
# 1688| ValueCategory = prvalue
12951+
# 1688| getFieldExpr(x): [VariableAccess] x
12952+
# 1688| Type = [IntType] int
12953+
# 1688| ValueCategory = prvalue(load)
12954+
# 1688| getFieldExpr(y): [VariableAccess] y
12955+
# 1688| Type = [LValueReferenceType] int &
12956+
# 1688| ValueCategory = prvalue(load)
12957+
# 1688| getFieldExpr(z): [VariableAccess] z
12958+
# 1688| Type = [RValueReferenceType] int &&
12959+
# 1688| ValueCategory = prvalue(load)
12960+
# 1690| getFieldExpr(y).getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
12961+
# 1690| Type = [IntType] int
12962+
# 1690| ValueCategory = prvalue(load)
12963+
# 1690| getFieldExpr(z).getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
12964+
# 1690| Type = [IntType] int
12965+
# 1690| ValueCategory = prvalue(load)
12966+
# 1691| getStmt(3): [ReturnStmt] return ...
12967+
# 1688| [CopyAssignmentOperator] (void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)& (void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)::operator=((void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25) const&)
12968+
# 1688| <params>:
12969+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
12970+
#-----| Type = [LValueReferenceType] const lambda [] type at line 1688, col. 25 &
12971+
# 1688| [CopyConstructor] void (void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)::(unnamed constructor)((void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25) const&)
12972+
# 1688| <params>:
12973+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
12974+
#-----| Type = [LValueReferenceType] const lambda [] type at line 1688, col. 25 &
12975+
# 1688| [MoveConstructor] void (void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)::(unnamed constructor)((void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)&&)
12976+
# 1688| <params>:
12977+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
12978+
#-----| Type = [RValueReferenceType] lambda [] type at line 1688, col. 25 &&
12979+
# 1688| [Constructor] void (void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)::(unnamed constructor)()
12980+
# 1688| <params>:
12981+
# 1688| [ConstMemberFunction] void (void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)::operator()() const
12982+
# 1688| <params>:
12983+
# 1688| getEntryPoint(): [BlockStmt] { ... }
12984+
# 1689| getStmt(0): [DeclStmt] declaration
12985+
# 1689| getDeclarationEntry(0): [VariableDeclarationEntry] definition of lambda_inner
12986+
# 1689| Type = [Closure,LocalClass] decltype([...](...){...})
12987+
# 1689| getVariable().getInitializer(): [Initializer] initializer for lambda_inner
12988+
# 1689| getExpr(): [LambdaExpression] [...](...){...}
12989+
# 1689| Type = [Closure,LocalClass] decltype([...](...){...})
12990+
# 1689| ValueCategory = prvalue
12991+
# 1689| getInitializer(): [ClassAggregateLiteral] {...}
12992+
# 1689| Type = [Closure,LocalClass] decltype([...](...){...})
12993+
# 1689| ValueCategory = prvalue
12994+
# 1689| getFieldExpr(obj1): [Literal] Unknown literal
12995+
# 1689| Type = [SpecifiedType] const CapturedLambdaMyObj
12996+
# 1689| ValueCategory = prvalue
12997+
# 1689| getFieldExpr(obj2): [Literal] Unknown literal
12998+
# 1689| Type = [Class] CapturedLambdaMyObj
12999+
# 1689| ValueCategory = prvalue
13000+
# 1689| getFieldExpr(x): [PointerFieldAccess] x
13001+
# 1689| Type = [IntType] int
13002+
# 1689| ValueCategory = prvalue(load)
13003+
# 1689| getQualifier(): [ThisExpr] this
13004+
# 1689| Type = [PointerType] const lambda [] type at line 1688, col. 25 *
13005+
# 1689| ValueCategory = prvalue(load)
13006+
# 1689| getFieldExpr(y): [PointerFieldAccess] y
13007+
# 1689| Type = [IntType] int
13008+
# 1689| ValueCategory = prvalue(load)
13009+
# 1689| getQualifier(): [ThisExpr] this
13010+
# 1689| Type = [PointerType] const lambda [] type at line 1688, col. 25 *
13011+
# 1689| ValueCategory = prvalue(load)
13012+
# 1689| getFieldExpr(z): [PointerFieldAccess] z
13013+
# 1689| Type = [IntType] int
13014+
# 1689| ValueCategory = prvalue(load)
13015+
# 1689| getQualifier(): [ThisExpr] this
13016+
# 1689| Type = [PointerType] const lambda [] type at line 1688, col. 25 *
13017+
# 1689| ValueCategory = prvalue(load)
13018+
# 1690| getStmt(1): [ReturnStmt] return ...
13019+
# 1689| [CopyAssignmentOperator] (void (void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)::operator()() const)::(lambda [] type at line 1689, col. 29)& (void (void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)::operator()() const)::(lambda [] type at line 1689, col. 29)::operator=((void (void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)::operator()() const)::(lambda [] type at line 1689, col. 29) const&)
13020+
# 1689| <params>:
13021+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
13022+
#-----| Type = [LValueReferenceType] const lambda [] type at line 1689, col. 29 &
13023+
# 1689| [CopyConstructor] void (void (void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)::operator()() const)::(lambda [] type at line 1689, col. 29)::(unnamed constructor)((void (void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)::operator()() const)::(lambda [] type at line 1689, col. 29) const&)
13024+
# 1689| <params>:
13025+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
13026+
#-----| Type = [LValueReferenceType] const lambda [] type at line 1689, col. 29 &
13027+
# 1689| [MoveConstructor] void (void (void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)::operator()() const)::(lambda [] type at line 1689, col. 29)::(unnamed constructor)((void (void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)::operator()() const)::(lambda [] type at line 1689, col. 29)&&)
13028+
# 1689| <params>:
13029+
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
13030+
#-----| Type = [RValueReferenceType] lambda [] type at line 1689, col. 29 &&
13031+
# 1689| [Constructor] void (void (void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)::operator()() const)::(lambda [] type at line 1689, col. 29)::(unnamed constructor)()
13032+
# 1689| <params>:
13033+
# 1689| [ConstMemberFunction] void (void (void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)::operator()() const)::(lambda [] type at line 1689, col. 29)::operator()() const
13034+
# 1689| <params>:
13035+
# 1689| getEntryPoint(): [BlockStmt] { ... }
13036+
# 1689| getStmt(0): [EmptyStmt] ;
13037+
# 1689| getStmt(1): [ReturnStmt] return ...
1282313038
perf-regression.cpp:
1282413039
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
1282513040
# 4| <params>:

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ missingOperandType
66
duplicateChiOperand
77
sideEffectWithoutPrimary
88
instructionWithoutSuccessor
9+
| ir.cpp:1688:24:1690:5 | FieldAddress: {...} | Instruction 'FieldAddress: {...}' has no successors in function '$@'. | ir.cpp:1683:6:1683:20 | void captured_lambda(int, int&, int&&) | void captured_lambda(int, int&, int&&) |
10+
| ir.cpp:1689:28:1689:54 | FieldAddress: {...} | Instruction 'FieldAddress: {...}' has no successors in function '$@'. | ir.cpp:1688:46:1688:46 | void (void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)::operator()() const | void (void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)::operator()() const |
911
ambiguousSuccessors
1012
unexplainedLoop
1113
unnecessaryPhiInstruction

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ missingOperandType
66
duplicateChiOperand
77
sideEffectWithoutPrimary
88
instructionWithoutSuccessor
9+
| ir.cpp:1688:24:1690:5 | FieldAddress: {...} | Instruction 'FieldAddress: {...}' has no successors in function '$@'. | ir.cpp:1683:6:1683:20 | void captured_lambda(int, int&, int&&) | void captured_lambda(int, int&, int&&) |
10+
| ir.cpp:1689:28:1689:54 | FieldAddress: {...} | Instruction 'FieldAddress: {...}' has no successors in function '$@'. | ir.cpp:1688:46:1688:46 | void (void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)::operator()() const | void (void captured_lambda(int, int&, int&&))::(lambda [] type at line 1688, col. 25)::operator()() const |
911
ambiguousSuccessors
1012
unexplainedLoop
1113
unnecessaryPhiInstruction

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,4 +1669,25 @@ void tuple_structured_binding_no_ref_get() {
16691669
}
16701670
}
16711671

1672+
void array_structured_binding_non_ref_init() {
1673+
int xs[2] = {1, 2};
1674+
auto [x0, x1] = xs;
1675+
}
1676+
1677+
class CapturedLambdaMyObj
1678+
{
1679+
public:
1680+
CapturedLambdaMyObj() {}
1681+
};
1682+
1683+
void captured_lambda(int x, int &y, int &&z)
1684+
{
1685+
const auto &obj1 = CapturedLambdaMyObj();
1686+
auto obj2 = CapturedLambdaMyObj();
1687+
1688+
auto lambda_outer = [obj1, obj2, x, y, z](){
1689+
auto lambda_inner = [obj1, obj2, x, y, z](){;};
1690+
};
1691+
}
1692+
16721693
// semmle-extractor-options: -std=c++17 --clang

0 commit comments

Comments
 (0)