Skip to content

[move-function] Address feedback from previous test commits and add even more tests! #3991

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def test_swift_move_function(self):
self.process = self.target.LaunchSimple(None, None, os.getcwd())
threads = lldbutil.get_threads_stopped_at_breakpoint(
self.process, self.breakpoints[0])
self.assertTrue(len(threads) == 1)
self.assertEqual(len(threads), 1)
self.thread = threads[0]

self.do_check_copyable_value_test()
Expand All @@ -55,6 +55,10 @@ def test_swift_move_function(self):
# ccf is conditional control flow
self.do_check_copyable_value_ccf_true()
self.do_check_copyable_value_ccf_false()
self.do_check_copyable_var_ccf_true_reinit_out_block()
self.do_check_copyable_var_ccf_true_reinit_in_block()
self.do_check_copyable_var_ccf_false_reinit_out_block()
self.do_check_copyable_var_ccf_false_reinit_in_block()

def setUp(self):
TestBase.setUp(self)
Expand All @@ -68,9 +72,14 @@ def add_breakpoints(self, name, num_breakpoints):
pat = pattern.format(name, i+1)
brk = self.target.BreakpointCreateBySourceRegex(
pat, self.main_source_spec)
self.assertTrue(brk.GetNumLocations() > 0, VALID_BREAKPOINT)
self.assertGreater(brk.GetNumLocations(), 0, VALID_BREAKPOINT)
yield brk

def get_var(self, name):
frame = self.thread.frames[0]
self.assertTrue(frame.IsValid(), "Couldn't get a frame.")
return frame.FindVariable(name)

def do_setup_breakpoints(self):
self.breakpoints = []

Expand All @@ -88,126 +97,255 @@ def do_setup_breakpoints(self):
self.breakpoints.extend(
self.add_breakpoints('copyableValueCCFFalseTest',
3))
self.breakpoints.extend(
self.add_breakpoints('copyableVarTestCCFlowTrueReinitOutOfBlockTest',
5))
self.breakpoints.extend(
self.add_breakpoints('copyableVarTestCCFlowTrueReinitInBlockTest',
5))
self.breakpoints.extend(
self.add_breakpoints('copyableVarTestCCFlowFalseReinitOutOfBlockTest',
4))
self.breakpoints.extend(
self.add_breakpoints('copyableVarTestCCFlowFalseReinitInBlockTest', 3))

def do_check_copyable_value_test(self):
frame = self.thread.frames[0]
self.assertTrue(frame.IsValid(), "Couldn't get a frame.")

# We haven't defined varK yet.
varK = frame.FindVariable('k')
varK = self.get_var('k')

self.assertTrue(varK.value == None, "varK initialized too early?!")
self.assertIsNone(varK.value, "varK initialized too early?!")

# Go to break point 2. k should be valid.
self.runCmd('continue')
self.assertTrue(varK.unsigned > 0, "varK not initialized?!")
self.assertGreater(varK.unsigned, 0, "varK not initialized?!")

# Go to breakpoint 3. k should no longer be valid.
self.runCmd('continue')
self.assertTrue(varK.value == None, "K is live but was moved?!")
self.assertIsNone(varK.value, "K is live but was moved?!")

# Run so we hit the next breakpoint to jump to the next test's
# breakpoint.
self.runCmd('continue')

def do_check_copyable_var_test(self):
frame = self.thread.frames[0]
self.assertTrue(frame.IsValid(), "Couldn't get a frame.")

# We haven't defined varK yet.
varK = frame.FindVariable('k')
self.assertTrue(varK.value == None, "varK initialized too early?!")
varK = self.get_var('k')
self.assertIsNone(varK.value, "varK initialized too early?!")

# Go to break point 2. k should be valid.
self.runCmd('continue')
self.assertTrue(varK.unsigned > 0, "varK not initialized?!")
self.assertGreater(varK.unsigned, 0, "varK not initialized?!")

# Go to breakpoint 3. We invalidated k
self.runCmd('continue')
self.assertTrue(varK.value == None, "K is live but was moved?!")
self.assertIsNone(varK.value, "K is live but was moved?!")

# Go to the last breakpoint and make sure that k is reinitialized
# properly.
self.runCmd('continue')
self.assertTrue(varK.unsigned > 0, "varK not initialized")
self.assertGreater(varK.unsigned, 0, "varK not initialized")

# Run so we hit the next breakpoint to go to the next test.
self.runCmd('continue')

def do_check_addressonly_value_test(self):
frame = self.thread.frames[0]
self.assertTrue(frame.IsValid(), "Couldn't get a frame.")

# We haven't defined varK or varM yet... so we shouldn't have a summary.
varK = frame.FindVariable('k')
# We haven't defined varK yet.
varK = self.get_var('k')

# Go to break point 2. k should be valid and m should not be. Since M is
# a dbg.declare it is hard to test robustly that it is not initialized
# so we don't do so. We have an additional llvm.dbg.addr test where we
# move the other variable and show the correct behavior with
# llvm.dbg.declare.
self.runCmd('continue')

self.assertTrue(varK.unsigned > 0, "var not initialized?!")
self.assertGreater(varK.unsigned, 0, "var not initialized?!")

# Go to breakpoint 3.
self.runCmd('continue')
self.assertTrue(varK.unsigned == 0,
self.assertEqual(varK.unsigned, 0,
"dbg thinks varK is live despite move?!")

# Run so we hit the next breakpoint as part of the next test.
self.runCmd('continue')

def do_check_addressonly_var_test(self):
frame = self.thread.frames[0]
self.assertTrue(frame.IsValid(), "Couldn't get a frame.")

varK = frame.FindVariable('k')
varK = self.get_var('k')

# Go to break point 2. k should be valid.
self.runCmd('continue')
self.assertTrue(varK.unsigned > 0, "varK not initialized?!")
self.assertGreater(varK.unsigned, 0, "varK not initialized?!")

# Go to breakpoint 3. K was invalidated.
self.runCmd('continue')
self.assertTrue(varK.value == None, "K is live but was moved?!")
self.assertIsNone(varK.value, "K is live but was moved?!")

# Go to the last breakpoint and make sure that k is reinitialized
# properly.
self.runCmd('continue')
self.assertTrue(varK.unsigned > 0, "varK not initialized")
self.assertGreater(varK.unsigned, 0, "varK not initialized")

# Run so we hit the next breakpoint as part of the next test.
self.runCmd('continue')

def do_check_copyable_value_ccf_true(self):
frame = self.thread.frames[0]
self.assertTrue(frame.IsValid(), "Couldn't get a frame.")
varK = frame.FindVariable('k')
varK = self.get_var('k')

# Check at our start point that we do not have any state for varK and
# then continue to our next breakpoint.
self.assertTrue(varK.value == None, "varK should not have a value?!")
self.assertIsNone(varK.value, "varK should not have a value?!")
self.runCmd('continue')

# At this breakpoint, k should be defined since we are going to do
# something with it.
self.assertTrue(varK.value != None, "varK should have a value?!")
self.assertIsNotNone(varK.value, "varK should have a value?!")
self.runCmd('continue')

# At this breakpoint, we are now in the conditional control flow part of
# the loop. Make sure that we can see k still.
self.assertTrue(varK.value != None, "varK should have a value?!")
self.assertIsNotNone(varK.value, "varK should have a value?!")
self.runCmd('continue')

# Ok, we just performed the move. k should not be no longer initialized.
self.runCmd('fr v')
self.assertTrue(varK.value == None, "varK should not have a value?!")
self.assertIsNone(varK.value, "varK should not have a value?!")
self.runCmd('continue')

# Finally we left the conditional control flow part of the function. k
# should still be None.
self.assertTrue(varK.value == None, "varK should not have a value!")
self.assertIsNone(varK.value, "varK should not have a value!")

# Run again so we go and run to the next test.
self.runCmd('continue')

def do_check_copyable_value_ccf_false(self):
pass
varK = self.get_var('k')

# Check at our start point that we do not have any state for varK and
# then continue to our next breakpoint.
self.assertIsNone(varK.value, "varK should not have a value?!")
self.runCmd('continue')

# At this breakpoint, k should be defined since we are going to do
# something with it.
self.assertIsNotNone(varK.value, "varK should have a value?!")
self.runCmd('continue')

# At this breakpoint, we are now past the end of the conditional
# statement. We know due to the move checking that k can not have any
# uses that are reachable from the move. So it is safe to always not
# provide the value here.
self.assertIsNone(varK.value, "varK should have a value?!")

# Run again so we go and run to the next test.
self.runCmd('continue')

def do_check_copyable_var_ccf_true_reinit_out_block(self):
varK = self.get_var('k')

# At first we should not have a value for k.
self.assertEqual(varK.unsigned, 0, "varK should be nullptr!")
self.runCmd('continue')

# Now we are in the conditional true block. K should be defined since we
# are on the move itself.
self.assertGreater(varK.unsigned, 0, "varK should not be nullptr!")
self.runCmd('continue')

# Now we have executed the move and we are about to run code using
# m. Make sure that K is not available!
self.assertEqual(varK.unsigned, 0,
"varK was already moved! Should be nullptr")
self.runCmd('continue')

# We are now out of the conditional lexical block on the line of code
# that redefines k. k should still be not available.
self.assertEqual(varK.unsigned, 0,
"varK was already moved! Should be nullptr")
self.runCmd('continue')

# Ok, we have now reinit k and are about to call a method on it. We
# should be valid now.
self.assertGreater(varK.unsigned, 0,
"varK should have be reinitialized?!")

# Run again so we go and run to the next test.
self.runCmd('continue')

def do_check_copyable_var_ccf_true_reinit_in_block(self):
varK = self.get_var('k')

# At first we should not have a value for k.
self.assertEqual(varK.unsigned, 0, "varK should be nullptr!")
self.runCmd('continue')

# Now we are in the conditional true block. K should be defined since we
# are on the move itself.
self.assertGreater(varK.unsigned, 0, "varK should not be nullptr!")
self.runCmd('continue')

# Now we have executed the move and we are about to reinit k but have
# not yet. Make sure we are not available!
self.assertEqual(varK.unsigned, 0,
"varK was already moved! Should be nullptr")
self.runCmd('continue')

# We are now still inside the conditional part of the code, but have
# reinitialized varK.
self.assertGreater(varK.unsigned, 0,
"varK was reinit! Should be valid value!")
self.runCmd('continue')

# We now have left the conditional part of the function. k should still
# be available.
self.assertGreater(varK.unsigned, 0,
"varK should have be reinitialized?!")

# Run again so we go and run to the next test.
self.runCmd('continue')

def do_check_copyable_var_ccf_false_reinit_out_block(self):
varK = self.get_var('k')

# At first we should not have a value for k.
self.assertEqual(varK.unsigned, 0, "varK should be nullptr!")
self.runCmd('continue')

# Now we are right above the beginning of the false check. varK should
# still be valid.
self.assertGreater(varK.unsigned, 0, "varK should not be nullptr!")
self.runCmd('continue')

# Now we are after the conditional part of the code on the reinit
# line. Since this is reachable from the move and we haven't reinit yet,
# k should not be available.
self.assertEqual(varK.unsigned, 0,
"varK was already moved! Should be nullptr")
self.runCmd('continue')

# Ok, we have now reinit k and are about to call a method on it. We
# should be valid now.
self.assertGreater(varK.unsigned, 0,
"varK should have be reinitialized?!")

# Run again so we go and run to the next test.
self.runCmd('continue')

def do_check_copyable_var_ccf_false_reinit_in_block(self):
varK = self.get_var('k')

# At first we should not have a value for k.
self.assertEqual(varK.unsigned, 0, "varK should be nullptr!")
self.runCmd('continue')

# Now we are on the doSomething above the false check. So varK should be
# valid.
self.assertGreater(varK.unsigned, 0, "varK should not be nullptr!")
self.runCmd('continue')

# Now we are after the conditional scope. Since k was reinitialized in
# the conditional scope, along all paths we are valid so varK should
# still be available.
self.assertGreater(varK.unsigned, 0,
"varK should not be nullptr?!")

# Run again so we go and run to the next test.
self.runCmd('continue')
Loading