Skip to content

Commit b5b9585

Browse files
committed
[move-function] Add tests that show that the debugger displays variables correctly given usage of the move function.
These are the first end to end tests that validate that showing moved variables works correctly.
1 parent c7f1cb5 commit b5b9585

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)