Skip to content

Commit 161f586

Browse files
authored
Merge pull request #16097 from MathiasVP/add-coroutine-tests
C++: Add coroutine tests
2 parents c00e207 + aa94ee5 commit 161f586

9 files changed

+3377
-0
lines changed

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

Lines changed: 1704 additions & 0 deletions
Large diffs are not rendered by default.

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

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,91 @@ complex.c:
738738
# 58| v58_6(void) = AliasedUse : m58_3
739739
# 58| v58_7(void) = ExitFunction :
740740

741+
coroutines.cpp:
742+
# 87| co_returnable_void co_return_void()
743+
# 87| Block 0
744+
# 87| v87_1(void) = EnterFunction :
745+
# 87| m87_2(unknown) = AliasedDefinition :
746+
# 87| m87_3(unknown) = InitializeNonLocal :
747+
# 87| m87_4(unknown) = Chi : total:m87_2, partial:m87_3
748+
# 87| r87_5(glval<promise_type>) = VariableAddress[(unnamed local variable)] :
749+
# 87| m87_6(promise_type) = Uninitialized[(unnamed local variable)] : &:r87_5
750+
751+
# 91| co_returnable_value co_return_int(int)
752+
# 91| Block 0
753+
# 91| v91_1(void) = EnterFunction :
754+
# 91| m91_2(unknown) = AliasedDefinition :
755+
# 91| m91_3(unknown) = InitializeNonLocal :
756+
# 91| m91_4(unknown) = Chi : total:m91_2, partial:m91_3
757+
# 91| r91_5(glval<int>) = VariableAddress[i] :
758+
# 91| m91_6(int) = InitializeParameter[i] : &:r91_5
759+
#-----| r0_1(glval<int>) = VariableAddress[i] :
760+
#-----| r0_2(glval<int>) = VariableAddress[i] :
761+
#-----| r0_3(int) = Load[i] : &:r0_2, m91_6
762+
#-----| m0_4(int) = Store[i] : &:r0_1, r0_3
763+
# 91| r91_7(glval<promise_type>) = VariableAddress[(unnamed local variable)] :
764+
# 91| m91_8(promise_type) = Uninitialized[(unnamed local variable)] : &:r91_7
765+
766+
# 95| co_returnable_void co_yield_value_void(int)
767+
# 95| Block 0
768+
# 95| v95_1(void) = EnterFunction :
769+
# 95| m95_2(unknown) = AliasedDefinition :
770+
# 95| m95_3(unknown) = InitializeNonLocal :
771+
# 95| m95_4(unknown) = Chi : total:m95_2, partial:m95_3
772+
# 95| r95_5(glval<int>) = VariableAddress[i] :
773+
# 95| m95_6(int) = InitializeParameter[i] : &:r95_5
774+
#-----| r0_1(glval<int>) = VariableAddress[i] :
775+
#-----| r0_2(glval<int>) = VariableAddress[i] :
776+
#-----| r0_3(int) = Load[i] : &:r0_2, m95_6
777+
#-----| m0_4(int) = Store[i] : &:r0_1, r0_3
778+
# 95| r95_7(glval<promise_type>) = VariableAddress[(unnamed local variable)] :
779+
# 95| m95_8(promise_type) = Uninitialized[(unnamed local variable)] : &:r95_7
780+
781+
# 99| co_returnable_value co_yield_value_value(int)
782+
# 99| Block 0
783+
# 99| v99_1(void) = EnterFunction :
784+
# 99| m99_2(unknown) = AliasedDefinition :
785+
# 99| m99_3(unknown) = InitializeNonLocal :
786+
# 99| m99_4(unknown) = Chi : total:m99_2, partial:m99_3
787+
# 99| r99_5(glval<int>) = VariableAddress[i] :
788+
# 99| m99_6(int) = InitializeParameter[i] : &:r99_5
789+
#-----| r0_1(glval<int>) = VariableAddress[i] :
790+
#-----| r0_2(glval<int>) = VariableAddress[i] :
791+
#-----| r0_3(int) = Load[i] : &:r0_2, m99_6
792+
#-----| m0_4(int) = Store[i] : &:r0_1, r0_3
793+
# 99| r99_7(glval<promise_type>) = VariableAddress[(unnamed local variable)] :
794+
# 99| m99_8(promise_type) = Uninitialized[(unnamed local variable)] : &:r99_7
795+
796+
# 103| co_returnable_void co_yield_and_return_void(int)
797+
# 103| Block 0
798+
# 103| v103_1(void) = EnterFunction :
799+
# 103| m103_2(unknown) = AliasedDefinition :
800+
# 103| m103_3(unknown) = InitializeNonLocal :
801+
# 103| m103_4(unknown) = Chi : total:m103_2, partial:m103_3
802+
# 103| r103_5(glval<int>) = VariableAddress[i] :
803+
# 103| m103_6(int) = InitializeParameter[i] : &:r103_5
804+
#-----| r0_1(glval<int>) = VariableAddress[i] :
805+
#-----| r0_2(glval<int>) = VariableAddress[i] :
806+
#-----| r0_3(int) = Load[i] : &:r0_2, m103_6
807+
#-----| m0_4(int) = Store[i] : &:r0_1, r0_3
808+
# 103| r103_7(glval<promise_type>) = VariableAddress[(unnamed local variable)] :
809+
# 103| m103_8(promise_type) = Uninitialized[(unnamed local variable)] : &:r103_7
810+
811+
# 108| co_returnable_value co_yield_and_return_value(int)
812+
# 108| Block 0
813+
# 108| v108_1(void) = EnterFunction :
814+
# 108| m108_2(unknown) = AliasedDefinition :
815+
# 108| m108_3(unknown) = InitializeNonLocal :
816+
# 108| m108_4(unknown) = Chi : total:m108_2, partial:m108_3
817+
# 108| r108_5(glval<int>) = VariableAddress[i] :
818+
# 108| m108_6(int) = InitializeParameter[i] : &:r108_5
819+
#-----| r0_1(glval<int>) = VariableAddress[i] :
820+
#-----| r0_2(glval<int>) = VariableAddress[i] :
821+
#-----| r0_3(int) = Load[i] : &:r0_2, m108_6
822+
#-----| m0_4(int) = Store[i] : &:r0_1, r0_3
823+
# 108| r108_7(glval<promise_type>) = VariableAddress[(unnamed local variable)] :
824+
# 108| m108_8(promise_type) = Uninitialized[(unnamed local variable)] : &:r108_7
825+
741826
destructors_for_temps.cpp:
742827
# 9| void ClassWithConstructor::ClassWithConstructor(ClassWithConstructor&&)
743828
# 9| Block 0

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ missingOperandType
66
duplicateChiOperand
77
sideEffectWithoutPrimary
88
instructionWithoutSuccessor
9+
| coroutines.cpp:87:20:87:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
10+
| coroutines.cpp:91:21:91:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:91:21:91:33 | co_returnable_value co_return_int(int) | co_returnable_value co_return_int(int) |
11+
| coroutines.cpp:95:20:95:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:95:20:95:38 | co_returnable_void co_yield_value_void(int) | co_returnable_void co_yield_value_void(int) |
12+
| coroutines.cpp:99:21:99:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:99:21:99:40 | co_returnable_value co_yield_value_value(int) | co_returnable_value co_yield_value_value(int) |
13+
| coroutines.cpp:103:20:103:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:103:20:103:43 | co_returnable_void co_yield_and_return_void(int) | co_returnable_void co_yield_and_return_void(int) |
14+
| coroutines.cpp:108:21:108:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:108:21:108:45 | co_returnable_value co_yield_and_return_value(int) | co_returnable_value co_yield_and_return_value(int) |
915
ambiguousSuccessors
1016
unexplainedLoop
1117
unnecessaryPhiInstruction

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ missingOperandType
66
duplicateChiOperand
77
sideEffectWithoutPrimary
88
instructionWithoutSuccessor
9+
| coroutines.cpp:87:20:87:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
10+
| coroutines.cpp:91:21:91:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:91:21:91:33 | co_returnable_value co_return_int(int) | co_returnable_value co_return_int(int) |
11+
| coroutines.cpp:95:20:95:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:95:20:95:38 | co_returnable_void co_yield_value_void(int) | co_returnable_void co_yield_value_void(int) |
12+
| coroutines.cpp:99:21:99:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:99:21:99:40 | co_returnable_value co_yield_value_value(int) | co_returnable_value co_yield_value_value(int) |
13+
| coroutines.cpp:103:20:103:20 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:103:20:103:43 | co_returnable_void co_yield_and_return_void(int) | co_returnable_void co_yield_and_return_void(int) |
14+
| coroutines.cpp:108:21:108:21 | Uninitialized: declaration of (unnamed local variable) | Instruction 'Uninitialized: declaration of (unnamed local variable)' has no successors in function '$@'. | coroutines.cpp:108:21:108:45 | co_returnable_value co_yield_and_return_value(int) | co_returnable_value co_yield_and_return_value(int) |
915
ambiguousSuccessors
1016
unexplainedLoop
1117
unnecessaryPhiInstruction
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
namespace std {
2+
3+
template<class R, class... Args>
4+
struct coroutine_traits{
5+
using promise_type = R::promise_type;
6+
};
7+
8+
using nullptr_t = decltype(nullptr);
9+
10+
template<typename Promise>
11+
struct coroutine_handle {
12+
constexpr coroutine_handle() noexcept;
13+
constexpr coroutine_handle( std::nullptr_t ) noexcept;
14+
coroutine_handle(const coroutine_handle&) noexcept;
15+
coroutine_handle(coroutine_handle&&) noexcept;
16+
17+
static coroutine_handle from_promise(Promise&);
18+
coroutine_handle& operator=(nullptr_t) noexcept;
19+
coroutine_handle& operator=(const coroutine_handle&) noexcept;
20+
coroutine_handle& operator=(coroutine_handle&&) noexcept;
21+
constexpr operator coroutine_handle() const noexcept;
22+
23+
bool done() const;
24+
constexpr explicit operator bool() const noexcept;
25+
26+
void operator()() const;
27+
void resume() const;
28+
29+
void destroy() const;
30+
31+
Promise& promise() const;
32+
33+
constexpr void* address() const noexcept;
34+
static constexpr coroutine_handle from_address(void *);
35+
};
36+
37+
template<typename Promise>
38+
constexpr bool operator==(coroutine_handle<Promise>, coroutine_handle<Promise>) noexcept;
39+
40+
struct suspend_always {
41+
constexpr bool await_ready() const noexcept;
42+
template<typename Promise> constexpr void await_suspend(coroutine_handle<Promise>) const noexcept;
43+
constexpr void await_resume() const noexcept;
44+
};
45+
}
46+
47+
class co_returnable_void {
48+
public:
49+
struct promise_type;
50+
co_returnable_void(std::coroutine_handle<promise_type>);
51+
52+
co_returnable_void(co_returnable_void&) = delete;
53+
co_returnable_void(co_returnable_void&&) = delete;
54+
};
55+
56+
struct co_returnable_void::promise_type {
57+
std::coroutine_handle<promise_type> get_return_object();
58+
std::suspend_always initial_suspend() noexcept;
59+
std::suspend_always final_suspend() noexcept;
60+
61+
void return_void();
62+
void unhandled_exception();
63+
64+
std::suspend_always yield_value(int);
65+
};
66+
67+
class co_returnable_value {
68+
public:
69+
struct promise_type;
70+
co_returnable_value(std::coroutine_handle<promise_type>);
71+
72+
co_returnable_value(co_returnable_value&) = delete;
73+
co_returnable_value(co_returnable_value&&) = delete;
74+
};
75+
76+
struct co_returnable_value::promise_type {
77+
std::coroutine_handle<promise_type> get_return_object();
78+
std::suspend_always initial_suspend() noexcept;
79+
std::suspend_always final_suspend() noexcept;
80+
81+
void return_value(int);
82+
void unhandled_exception();
83+
84+
std::suspend_always yield_value(int);
85+
};
86+
87+
co_returnable_void co_return_void() {
88+
co_return;
89+
}
90+
91+
co_returnable_value co_return_int(int i) {
92+
co_return i;
93+
}
94+
95+
co_returnable_void co_yield_value_void(int i) {
96+
co_yield i;
97+
}
98+
99+
co_returnable_value co_yield_value_value(int i) {
100+
co_yield i;
101+
}
102+
103+
co_returnable_void co_yield_and_return_void(int i) {
104+
co_yield i;
105+
co_return;
106+
}
107+
108+
co_returnable_value co_yield_and_return_value(int i) {
109+
co_yield i;
110+
co_return (i + 1);
111+
}
112+
113+
114+
115+
// semmle-extractor-options: --edg --c++20

0 commit comments

Comments
 (0)