Skip to content

Commit eee7d51

Browse files
authored
Merge pull request #3986 from gottesmm/stable/20211026/move-function-tests
[move-function] Add tests that show that the debugger displays variables correctly given usage of the move function.
2 parents cbd3863 + b5b9585 commit eee7d51

File tree

3 files changed

+323
-0
lines changed

3 files changed

+323
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SWIFT_SOURCES := main.swift
2+
3+
include Makefile.rules
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
# TestSwiftMoveFunction.py
2+
#
3+
# This source file is part of the Swift.org open source project
4+
#
5+
# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
# Licensed under Apache License v2.0 with Runtime Library Exception
7+
#
8+
# See https://swift.org/LICENSE.txt for license information
9+
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
#
11+
# ------------------------------------------------------------------------------
12+
"""
13+
Check that we properly show variables at various points of the CFG while
14+
stepping with the move function.
15+
"""
16+
import lldb
17+
from lldbsuite.test.lldbtest import *
18+
from lldbsuite.test.decorators import *
19+
import lldbsuite.test.lldbutil as lldbutil
20+
import os
21+
import sys
22+
import unittest2
23+
24+
def stderr_print(line):
25+
sys.stderr.write(line + "\n")
26+
27+
class TestSwiftMoveFunctionType(TestBase):
28+
29+
mydir = TestBase.compute_mydir(__file__)
30+
31+
@skipUnlessPlatform(["macosx"])
32+
@swiftTest
33+
def test_swift_move_function(self):
34+
"""Check that we properly show variables at various points of the CFG while
35+
stepping with the move function.
36+
"""
37+
self.build()
38+
39+
self.exec_artifact = self.getBuildArtifact(self.exec_name)
40+
self.target = self.dbg.CreateTarget(self.exec_artifact)
41+
self.assertTrue(self.target, VALID_TARGET)
42+
43+
self.do_setup_breakpoints()
44+
45+
self.process = self.target.LaunchSimple(None, None, os.getcwd())
46+
threads = lldbutil.get_threads_stopped_at_breakpoint(
47+
self.process, self.breakpoints[0])
48+
self.assertTrue(len(threads) == 1)
49+
self.thread = threads[0]
50+
51+
self.do_check_copyable_value_test()
52+
self.do_check_copyable_var_test()
53+
self.do_check_addressonly_value_test()
54+
self.do_check_addressonly_var_test()
55+
# ccf is conditional control flow
56+
self.do_check_copyable_value_ccf_true()
57+
self.do_check_copyable_value_ccf_false()
58+
59+
def setUp(self):
60+
TestBase.setUp(self)
61+
self.main_source = "main.swift"
62+
self.main_source_spec = lldb.SBFileSpec(self.main_source)
63+
self.exec_name = "a.out"
64+
65+
def add_breakpoints(self, name, num_breakpoints):
66+
pattern = 'Set breakpoint {} here {}'
67+
for i in range(num_breakpoints):
68+
pat = pattern.format(name, i+1)
69+
brk = self.target.BreakpointCreateBySourceRegex(
70+
pat, self.main_source_spec)
71+
self.assertTrue(brk.GetNumLocations() > 0, VALID_BREAKPOINT)
72+
yield brk
73+
74+
def do_setup_breakpoints(self):
75+
self.breakpoints = []
76+
77+
self.breakpoints.extend(
78+
self.add_breakpoints('copyableValueTest', 3))
79+
self.breakpoints.extend(
80+
self.add_breakpoints('addressOnlyValueTest', 3))
81+
self.breakpoints.extend(
82+
self.add_breakpoints('copyableVarTest', 4))
83+
self.breakpoints.extend(
84+
self.add_breakpoints('addressOnlyVarTest', 4))
85+
self.breakpoints.extend(
86+
self.add_breakpoints('copyableValueCCFTrueTest',
87+
5))
88+
self.breakpoints.extend(
89+
self.add_breakpoints('copyableValueCCFFalseTest',
90+
3))
91+
92+
def do_check_copyable_value_test(self):
93+
frame = self.thread.frames[0]
94+
self.assertTrue(frame.IsValid(), "Couldn't get a frame.")
95+
96+
# We haven't defined varK yet.
97+
varK = frame.FindVariable('k')
98+
99+
self.assertTrue(varK.value == None, "varK initialized too early?!")
100+
101+
# Go to break point 2. k should be valid.
102+
self.runCmd('continue')
103+
self.assertTrue(varK.unsigned > 0, "varK not initialized?!")
104+
105+
# Go to breakpoint 3. k should no longer be valid.
106+
self.runCmd('continue')
107+
self.assertTrue(varK.value == None, "K is live but was moved?!")
108+
109+
# Run so we hit the next breakpoint to jump to the next test's
110+
# breakpoint.
111+
self.runCmd('continue')
112+
113+
def do_check_copyable_var_test(self):
114+
frame = self.thread.frames[0]
115+
self.assertTrue(frame.IsValid(), "Couldn't get a frame.")
116+
117+
# We haven't defined varK yet.
118+
varK = frame.FindVariable('k')
119+
self.assertTrue(varK.value == None, "varK initialized too early?!")
120+
121+
# Go to break point 2. k should be valid.
122+
self.runCmd('continue')
123+
self.assertTrue(varK.unsigned > 0, "varK not initialized?!")
124+
125+
# Go to breakpoint 3. We invalidated k
126+
self.runCmd('continue')
127+
self.assertTrue(varK.value == None, "K is live but was moved?!")
128+
129+
# Go to the last breakpoint and make sure that k is reinitialized
130+
# properly.
131+
self.runCmd('continue')
132+
self.assertTrue(varK.unsigned > 0, "varK not initialized")
133+
134+
# Run so we hit the next breakpoint to go to the next test.
135+
self.runCmd('continue')
136+
137+
def do_check_addressonly_value_test(self):
138+
frame = self.thread.frames[0]
139+
self.assertTrue(frame.IsValid(), "Couldn't get a frame.")
140+
141+
# We haven't defined varK or varM yet... so we shouldn't have a summary.
142+
varK = frame.FindVariable('k')
143+
144+
# Go to break point 2. k should be valid and m should not be. Since M is
145+
# a dbg.declare it is hard to test robustly that it is not initialized
146+
# so we don't do so. We have an additional llvm.dbg.addr test where we
147+
# move the other variable and show the correct behavior with
148+
# llvm.dbg.declare.
149+
self.runCmd('continue')
150+
151+
self.assertTrue(varK.unsigned > 0, "var not initialized?!")
152+
153+
# Go to breakpoint 3.
154+
self.runCmd('continue')
155+
self.assertTrue(varK.unsigned == 0,
156+
"dbg thinks varK is live despite move?!")
157+
158+
# Run so we hit the next breakpoint as part of the next test.
159+
self.runCmd('continue')
160+
161+
def do_check_addressonly_var_test(self):
162+
frame = self.thread.frames[0]
163+
self.assertTrue(frame.IsValid(), "Couldn't get a frame.")
164+
165+
varK = frame.FindVariable('k')
166+
167+
# Go to break point 2. k should be valid.
168+
self.runCmd('continue')
169+
self.assertTrue(varK.unsigned > 0, "varK not initialized?!")
170+
171+
# Go to breakpoint 3. K was invalidated.
172+
self.runCmd('continue')
173+
self.assertTrue(varK.value == None, "K is live but was moved?!")
174+
175+
# Go to the last breakpoint and make sure that k is reinitialized
176+
# properly.
177+
self.runCmd('continue')
178+
self.assertTrue(varK.unsigned > 0, "varK not initialized")
179+
180+
# Run so we hit the next breakpoint as part of the next test.
181+
self.runCmd('continue')
182+
183+
def do_check_copyable_value_ccf_true(self):
184+
frame = self.thread.frames[0]
185+
self.assertTrue(frame.IsValid(), "Couldn't get a frame.")
186+
varK = frame.FindVariable('k')
187+
188+
# Check at our start point that we do not have any state for varK and
189+
# then continue to our next breakpoint.
190+
self.assertTrue(varK.value == None, "varK should not have a value?!")
191+
self.runCmd('continue')
192+
193+
# At this breakpoint, k should be defined since we are going to do
194+
# something with it.
195+
self.assertTrue(varK.value != None, "varK should have a value?!")
196+
self.runCmd('continue')
197+
198+
# At this breakpoint, we are now in the conditional control flow part of
199+
# the loop. Make sure that we can see k still.
200+
self.assertTrue(varK.value != None, "varK should have a value?!")
201+
self.runCmd('continue')
202+
203+
# Ok, we just performed the move. k should not be no longer initialized.
204+
self.runCmd('fr v')
205+
self.assertTrue(varK.value == None, "varK should not have a value?!")
206+
self.runCmd('continue')
207+
208+
# Finally we left the conditional control flow part of the function. k
209+
# should still be None.
210+
self.assertTrue(varK.value == None, "varK should not have a value!")
211+
212+
def do_check_copyable_value_ccf_false(self):
213+
pass
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// main.swift
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
// -----------------------------------------------------------------------------
12+
13+
public class Klass {
14+
public func doSomething() {}
15+
}
16+
17+
public protocol P {
18+
static var value: P { get }
19+
func doSomething()
20+
}
21+
22+
extension Klass : P {
23+
public static var value: P { Klass() }
24+
}
25+
26+
var trueBoolValue : Bool { true }
27+
var falseBoolValue : Bool { false }
28+
29+
//////////////////
30+
// Simple Tests //
31+
//////////////////
32+
33+
public func copyableValueTest() {
34+
print("stop here") // Set breakpoint copyableValueTest here 1
35+
let k = Klass()
36+
k.doSomething()
37+
let m = _move(k) // Set breakpoint copyableValueTest here 2
38+
m.doSomething() // Set breakpoint copyableValueTest here 3
39+
}
40+
41+
public func copyableVarTest() {
42+
print("stop here") // Set breakpoint copyableVarTest here 1
43+
var k = Klass()
44+
k.doSomething()
45+
let m = _move(k) // Set breakpoint copyableVarTest here 2
46+
m.doSomething()
47+
k = Klass() // Set breakpoint copyableVarTest here 3
48+
k.doSomething() // Set breakpoint copyableVarTest here 4
49+
print("stop here")
50+
}
51+
52+
public func addressOnlyValueTest<T : P>(_ x: T) {
53+
print("stop here") // Set breakpoint addressOnlyValueTest here 1
54+
let k = x
55+
k.doSomething()
56+
let m = _move(k) // Set breakpoint addressOnlyValueTest here 2
57+
m.doSomething() // Set breakpoint addressOnlyValueTest here 3
58+
}
59+
60+
public func addressOnlyVarTest<T : P>(_ x: T) {
61+
print("stop here") // Set breakpoint addressOnlyVarTest here 1
62+
var k = x
63+
k.doSomething()
64+
let m = _move(k) // Set breakpoint addressOnlyVarTest here 2
65+
m.doSomething()
66+
k = x // Set breakpoint addressOnlyVarTest here 3
67+
k.doSomething() // Set breakpoint addressOnlyVarTest here 4
68+
}
69+
70+
////////////////////////////////////
71+
// Conditional Control Flow Tests //
72+
////////////////////////////////////
73+
74+
public func copyableValueCCFTrueTest() {
75+
let k = Klass() // Set breakpoint copyableValueCCFTrueTest here 1
76+
k.doSomething() // Set breakpoint copyableValueCCFTrueTest here 2
77+
if trueBoolValue {
78+
let m = _move(k) // Set breakpoint copyableValueCCFTrueTest here 3
79+
m.doSomething() // Set breakpoint copyableValueCCFTrueTest here 4
80+
}
81+
// Set breakpoint copyableValueCCFTrueTest here 5
82+
}
83+
84+
public func copyableValueCCFFalseTest() {
85+
let k = Klass() // Set breakpoint copyableValueCCFFalseTest here 1
86+
k.doSomething()
87+
if falseBoolValue { // Set breakpoint copyableValueCCFFalseTest here 2
88+
let m = _move(k)
89+
m.doSomething()
90+
}
91+
// Set breakpoint copyableValueCCFFalseTest here 3
92+
}
93+
94+
//////////////////////////
95+
// Top Level Entrypoint //
96+
//////////////////////////
97+
98+
func main() {
99+
copyableValueTest()
100+
copyableVarTest()
101+
addressOnlyValueTest(Klass())
102+
addressOnlyVarTest(Klass())
103+
copyableValueCCFTrueTest()
104+
copyableValueCCFFalseTest()
105+
}
106+
107+
main()

0 commit comments

Comments
 (0)