Author: Jim Ingham
Date: 2021-01-20T17:58:34-08:00
New Revision: bff389120fa2368d123612449c938958cfd7f45e
URL:
https://github.com/llvm/llvm-project/commit/bff389120fa2368d123612449c938958cfd7f45e
DIFF:
https://github.com/llvm/llvm-project/commit/bff389120fa2368d123612449c938958cfd7f45e.diff
LOG: Fix a bug with setting breakpoints on C++11 inline initialization
statements.
If they occurred before the constructor that used them, we would refuse to
set the breakpoint because we thought they were crossing function boundaries.
Differential Revision: https://reviews.llvm.org/D94846
Added:
lldb/test/API/lang/cpp/break-on-initializers/Makefile
lldb/test/API/lang/cpp/break-on-initializers/TestBreakOnCPP11Initializers.py
lldb/test/API/lang/cpp/break-on-initializers/main.cpp
Modified:
lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
Removed:
diff --git a/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
b/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
index 22a4b4ae33ae..5ca4ef5834e0 100644
--- a/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
@@ -187,6 +187,14 @@ void
BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list,
// is 0, then we can't do this calculation. That can happen if
// GetStartLineSourceInfo gets an error, or if the first line number in
// the function really is 0 - which happens for some languages.
+
+// But only do this calculation if the line number we found in the SC
+// was
diff erent from the one requested in the source file. If we actually
+// found an exact match it must be valid.
+
+if (m_line_number == sc.line_entry.line)
+ continue;
+
const int decl_line_is_too_late_fudge = 1;
if (line && m_line_number < line - decl_line_is_too_late_fudge) {
LLDB_LOG(log, "removing symbol context at {0}:{1}", file, line);
diff --git a/lldb/test/API/lang/cpp/break-on-initializers/Makefile
b/lldb/test/API/lang/cpp/break-on-initializers/Makefile
new file mode 100644
index ..7714f26e52bc
--- /dev/null
+++ b/lldb/test/API/lang/cpp/break-on-initializers/Makefile
@@ -0,0 +1,4 @@
+C_SOURCES := main.c
+CXXFLAGS_EXTRAS := -std=c++11
+
+include Makefile.rules
diff --git
a/lldb/test/API/lang/cpp/break-on-initializers/TestBreakOnCPP11Initializers.py
b/lldb/test/API/lang/cpp/break-on-initializers/TestBreakOnCPP11Initializers.py
new file mode 100644
index ..8456a7cae96e
--- /dev/null
+++
b/lldb/test/API/lang/cpp/break-on-initializers/TestBreakOnCPP11Initializers.py
@@ -0,0 +1,52 @@
+"""
+When using C++11 in place member initialization, show that we
+can set and hit breakpoints on initialization lines. This is a
+little bit tricky because we try not to move file and line breakpoints
+across function boundaries but these lines are outside the source range
+of the constructor.
+"""
+
+
+
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+
+class RenameThisSampleTestTestCase(TestBase):
+
+mydir = TestBase.compute_mydir(__file__)
+
+def test_breakpoints_on_initializers(self):
+"""Show we can set breakpoints on initializers appearing both before
+ and after the constructor body, and hit them."""
+self.build()
+self.main_source_file = lldb.SBFileSpec("main.cpp")
+self.first_initializer_line = line_number("main.cpp", "Set the before
constructor breakpoint here")
+self.second_initializer_line = line_number("main.cpp", "Set the after
constructor breakpoint here")
+self.sample_test()
+
+def setUp(self):
+# Call super's setUp().
+TestBase.setUp(self)
+# Set up your test case here. If your test doesn't need any set up then
+# remove this method from your TestCase class.
+
+def sample_test(self):
+"""You might use the test implementation in several ways, say so
here."""
+
+(target, process, thread, bkpt) =
lldbutil.run_to_source_breakpoint(self,
+ " Set a breakpoint here to get started",
self.main_source_file)
+
+# Now set breakpoints on the two initializer lines we found in the
test startup:
+bkpt1 = target.BreakpointCreateByLocation(self.main_source_file,
self.first_initializer_line)
+self.assertEqual(bkpt1.GetNumLocations(), 1)
+bkpt2 = target.BreakpointCreateByLocation(self.main_source_file,
self.second_initializer_line)
+self.assertEqual(bkpt2.GetNumLocations(), 1)
+
+# Now continue, we should stop at the two breakpoints above, first the
one before, then
+# the one after.
+self.assertEqual(len(lldbutil.continue_to_breakpoint(process, bkpt1)),
1, "Hit first breakpoint")
+self.assertEqual(len(lldbutil.continue_to_breakpoint(process, bkpt2