clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name BlockPointer.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-8/lib/clang/8.0.0 -D HAVE_ROUND -D LLDB_CONFIGURATION_RELEASE -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/source/Plugins/Language/CPlusPlus -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/Language/CPlusPlus -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn345461/include -I /usr/include/python2.7 -I /build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/../clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/. -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-deprecated-register -Wno-vla-extension -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/source/Plugins/Language/CPlusPlus -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-10-27-211344-32123-1 -x c++ /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp -faddrsig
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #include "BlockPointer.h" |
15 | |
16 | #include "lldb/Core/ValueObject.h" |
17 | #include "lldb/DataFormatters/FormattersHelpers.h" |
18 | #include "lldb/Symbol/ClangASTContext.h" |
19 | #include "lldb/Symbol/ClangASTImporter.h" |
20 | #include "lldb/Symbol/CompilerType.h" |
21 | #include "lldb/Symbol/TypeSystem.h" |
22 | #include "lldb/Target/Target.h" |
23 | |
24 | #include "lldb/Utility/LLDBAssert.h" |
25 | |
26 | using namespace lldb; |
27 | using namespace lldb_private; |
28 | using namespace lldb_private::formatters; |
29 | |
30 | namespace lldb_private { |
31 | namespace formatters { |
32 | |
33 | class BlockPointerSyntheticFrontEnd : public SyntheticChildrenFrontEnd { |
34 | public: |
35 | BlockPointerSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) |
36 | : SyntheticChildrenFrontEnd(*valobj_sp), m_block_struct_type() { |
37 | CompilerType block_pointer_type(m_backend.GetCompilerType()); |
38 | CompilerType function_pointer_type; |
39 | block_pointer_type.IsBlockPointerType(&function_pointer_type); |
40 | |
41 | TargetSP target_sp(m_backend.GetTargetSP()); |
42 | |
43 | if (!target_sp) { |
44 | return; |
45 | } |
46 | |
47 | Status err; |
48 | TypeSystem *type_system = target_sp->GetScratchTypeSystemForLanguage( |
49 | &err, lldb::eLanguageTypeC_plus_plus); |
50 | |
51 | if (!err.Success() || !type_system) { |
52 | return; |
53 | } |
54 | |
55 | ClangASTContext *clang_ast_context = |
56 | llvm::dyn_cast<ClangASTContext>(type_system); |
57 | |
58 | if (!clang_ast_context) { |
59 | return; |
60 | } |
61 | |
62 | ClangASTImporterSP clang_ast_importer = target_sp->GetClangASTImporter(); |
63 | |
64 | if (!clang_ast_importer) { |
65 | return; |
66 | } |
67 | |
68 | const char *const isa_name("__isa"); |
69 | const CompilerType isa_type = |
70 | clang_ast_context->GetBasicType(lldb::eBasicTypeObjCClass); |
71 | const char *const flags_name("__flags"); |
72 | const CompilerType flags_type = |
73 | clang_ast_context->GetBasicType(lldb::eBasicTypeInt); |
74 | const char *const reserved_name("__reserved"); |
75 | const CompilerType reserved_type = |
76 | clang_ast_context->GetBasicType(lldb::eBasicTypeInt); |
77 | const char *const FuncPtr_name("__FuncPtr"); |
78 | const CompilerType FuncPtr_type = |
79 | clang_ast_importer->CopyType(*clang_ast_context, function_pointer_type); |
80 | |
81 | m_block_struct_type = clang_ast_context->CreateStructForIdentifier( |
82 | ConstString(), {{isa_name, isa_type}, |
83 | {flags_name, flags_type}, |
84 | {reserved_name, reserved_type}, |
85 | {FuncPtr_name, FuncPtr_type}}); |
86 | } |
87 | |
88 | ~BlockPointerSyntheticFrontEnd() override = default; |
89 | |
90 | size_t CalculateNumChildren() override { |
91 | const bool omit_empty_base_classes = false; |
92 | return m_block_struct_type.GetNumChildren(omit_empty_base_classes); |
93 | } |
94 | |
95 | lldb::ValueObjectSP GetChildAtIndex(size_t idx) override { |
96 | if (!m_block_struct_type.IsValid()) { |
97 | return lldb::ValueObjectSP(); |
98 | } |
99 | |
100 | if (idx >= CalculateNumChildren()) { |
101 | return lldb::ValueObjectSP(); |
102 | } |
103 | |
104 | const bool thread_and_frame_only_if_stopped = true; |
105 | ExecutionContext exe_ctx = m_backend.GetExecutionContextRef().Lock( |
106 | thread_and_frame_only_if_stopped); |
107 | const bool transparent_pointers = false; |
108 | const bool omit_empty_base_classes = false; |
109 | const bool ignore_array_bounds = false; |
110 | ValueObject *value_object = nullptr; |
111 | |
112 | std::string child_name; |
113 | uint32_t child_byte_size = 0; |
114 | int32_t child_byte_offset = 0; |
115 | uint32_t child_bitfield_bit_size = 0; |
116 | uint32_t child_bitfield_bit_offset = 0; |
117 | bool child_is_base_class = false; |
118 | bool child_is_deref_of_parent = false; |
119 | uint64_t language_flags = 0; |
120 | |
121 | const CompilerType child_type = |
122 | m_block_struct_type.GetChildCompilerTypeAtIndex( |
123 | &exe_ctx, idx, transparent_pointers, omit_empty_base_classes, |
124 | ignore_array_bounds, child_name, child_byte_size, child_byte_offset, |
125 | child_bitfield_bit_size, child_bitfield_bit_offset, |
126 | child_is_base_class, child_is_deref_of_parent, value_object, |
127 | language_flags); |
128 | |
129 | ValueObjectSP struct_pointer_sp = |
130 | m_backend.Cast(m_block_struct_type.GetPointerType()); |
131 | |
132 | if (!struct_pointer_sp) { |
133 | return lldb::ValueObjectSP(); |
134 | } |
135 | |
136 | Status err; |
137 | ValueObjectSP struct_sp = struct_pointer_sp->Dereference(err); |
138 | |
139 | if (!struct_sp || !err.Success()) { |
140 | return lldb::ValueObjectSP(); |
141 | } |
142 | |
143 | ValueObjectSP child_sp(struct_sp->GetSyntheticChildAtOffset( |
144 | child_byte_offset, child_type, true, |
145 | ConstString(child_name.c_str(), child_name.size()))); |
146 | |
147 | return child_sp; |
148 | } |
149 | |
150 | |
151 | |
152 | bool Update() override { return false; } |
153 | |
154 | |
155 | bool MightHaveChildren() override { return true; } |
156 | |
157 | size_t GetIndexOfChildWithName(const ConstString &name) override { |
158 | if (!m_block_struct_type.IsValid()) |
159 | return UINT32_MAX(4294967295U); |
160 | |
161 | const bool omit_empty_base_classes = false; |
162 | return m_block_struct_type.GetIndexOfChildWithName(name.AsCString(), |
163 | omit_empty_base_classes); |
164 | } |
165 | |
166 | private: |
167 | CompilerType m_block_struct_type; |
168 | }; |
169 | |
170 | } |
171 | } |
172 | |
173 | bool lldb_private::formatters::BlockPointerSummaryProvider( |
174 | ValueObject &valobj, Stream &s, const TypeSummaryOptions &) { |
175 | lldb_private::SyntheticChildrenFrontEnd *synthetic_children = |
176 | BlockPointerSyntheticFrontEndCreator(nullptr, valobj.GetSP()); |
| 1 | Calling 'BlockPointerSyntheticFrontEndCreator' | |
|
| 4 | | Returned allocated memory | |
|
177 | if (!synthetic_children) { |
| |
178 | return false; |
179 | } |
180 | |
181 | synthetic_children->Update(); |
182 | |
183 | static const ConstString s_FuncPtr_name("__FuncPtr"); |
184 | |
185 | lldb::ValueObjectSP child_sp = synthetic_children->GetChildAtIndex( |
| 6 | | Potential leak of memory pointed to by 'synthetic_children' |
|
186 | synthetic_children->GetIndexOfChildWithName(s_FuncPtr_name)); |
187 | |
188 | if (!child_sp) { |
189 | return false; |
190 | } |
191 | |
192 | lldb::ValueObjectSP qualified_child_representation_sp = |
193 | child_sp->GetQualifiedRepresentationIfAvailable( |
194 | lldb::eDynamicDontRunTarget, true); |
195 | |
196 | const char *child_value = |
197 | qualified_child_representation_sp->GetValueAsCString(); |
198 | |
199 | s.Printf("%s", child_value); |
200 | |
201 | return true; |
202 | } |
203 | |
204 | lldb_private::SyntheticChildrenFrontEnd * |
205 | lldb_private::formatters::BlockPointerSyntheticFrontEndCreator( |
206 | CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { |
207 | if (!valobj_sp) |
| |
208 | return nullptr; |
209 | return new BlockPointerSyntheticFrontEnd(valobj_sp); |
| |
210 | } |