Skip to content

Commit 15cde99

Browse files
authored
[LLDB] Check type before creating std::atomic synthetic children (llvm#163176)
From llvm#163077 (comment): Currently, `std::atomic<T>` will always use the MSVC STL synthetic children and summary. When inspecting types from other STLs, the output would not show any children. This PR adds a check that `std::atomic` contains `_Storage` to be classified as coming from MSVC's STL.
1 parent 14a7c8a commit 15cde99

File tree

7 files changed

+90
-2
lines changed

7 files changed

+90
-2
lines changed

lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,13 @@ lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::
142142
SyntheticChildrenFrontEnd *
143143
lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator(
144144
CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
145-
if (valobj_sp)
145+
if (valobj_sp && IsLibCxxAtomic(*valobj_sp))
146146
return new LibcxxStdAtomicSyntheticFrontEnd(valobj_sp);
147147
return nullptr;
148148
}
149+
150+
bool lldb_private::formatters::IsLibCxxAtomic(ValueObject &valobj) {
151+
if (auto valobj_sp = valobj.GetNonSyntheticValue())
152+
return valobj_sp->GetChildMemberWithName("__a_") != nullptr;
153+
return false;
154+
}

lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
namespace lldb_private {
1919
namespace formatters {
2020

21+
bool IsLibCxxAtomic(ValueObject &valobj);
22+
2123
lldb::ValueObjectSP GetLibCxxAtomicValue(ValueObject &valobj);
2224

2325
bool LibCxxAtomicSummaryProvider(ValueObject &valobj, Stream &stream,

lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ MsvcStlVariantSyntheticFrontEndCreator(CXXSyntheticChildren *,
8989
lldb::ValueObjectSP valobj_sp);
9090

9191
// MSVC STL std::atomic<>
92+
bool IsMsvcStlAtomic(ValueObject &valobj);
9293
bool MsvcStlAtomicSummaryProvider(ValueObject &valobj, Stream &stream,
9394
const TypeSummaryOptions &options);
9495
SyntheticChildrenFrontEnd *

lldb/source/Plugins/Language/CPlusPlus/MsvcStlAtomic.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ llvm::Expected<size_t> lldb_private::formatters::
8383
lldb_private::SyntheticChildrenFrontEnd *
8484
lldb_private::formatters::MsvcStlAtomicSyntheticFrontEndCreator(
8585
CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
86-
return new MsvcStlAtomicSyntheticFrontEnd(valobj_sp);
86+
if (valobj_sp && IsMsvcStlAtomic(*valobj_sp))
87+
return new MsvcStlAtomicSyntheticFrontEnd(valobj_sp);
88+
return nullptr;
8789
}
8890

8991
bool lldb_private::formatters::MsvcStlAtomicSummaryProvider(
@@ -100,3 +102,9 @@ bool lldb_private::formatters::MsvcStlAtomicSummaryProvider(
100102
}
101103
return false;
102104
}
105+
106+
bool lldb_private::formatters::IsMsvcStlAtomic(ValueObject &valobj) {
107+
if (auto valobj_sp = valobj.GetNonSyntheticValue())
108+
return valobj_sp->GetChildMemberWithName("_Storage") != nullptr;
109+
return false;
110+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CXX_SOURCES := main.cpp
2+
3+
include Makefile.rules
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
"""
2+
Test formatting of `std::atomic`s not from any STL
3+
"""
4+
5+
import lldb
6+
from lldbsuite.test.lldbtest import *
7+
from lldbsuite.test import lldbutil
8+
9+
10+
class InvalidAtomicDataFormatterTestCase(TestBase):
11+
def test(self):
12+
self.build()
13+
lldbutil.run_to_source_breakpoint(
14+
self, "Set break point at this line.", lldb.SBFileSpec("main.cpp")
15+
)
16+
17+
self.expect_expr(
18+
"a",
19+
result_children=[
20+
ValueCheck(name="foo", value="1"),
21+
ValueCheck(name="bar", value="2"),
22+
],
23+
)
24+
self.expect_expr(
25+
"b",
26+
result_children=[
27+
ValueCheck(name="foo", value="3"),
28+
ValueCheck(name="bar", value="4"),
29+
],
30+
)
31+
32+
self.expect_expr(
33+
"c",
34+
result_children=[
35+
ValueCheck(name="foo", value="5"),
36+
ValueCheck(name="bar", value="6"),
37+
],
38+
)
39+
self.expect_expr(
40+
"d",
41+
result_children=[
42+
ValueCheck(name="foo", value="7"),
43+
ValueCheck(name="bar", value="8"),
44+
],
45+
)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
namespace std {
2+
template <typename T> struct atomic {
3+
int foo;
4+
int bar;
5+
};
6+
7+
namespace __1 {
8+
template <typename T> struct atomic {
9+
int foo;
10+
int bar;
11+
};
12+
} // namespace __1
13+
} // namespace std
14+
15+
int main() {
16+
std::atomic<int> a{1, 2};
17+
std::atomic<void> b{3, 4};
18+
19+
std::__1::atomic<int> c{5, 6};
20+
std::__1::atomic<void> d{7, 8};
21+
22+
return 0; // Set break point at this line.
23+
}

0 commit comments

Comments
 (0)