From ec28e43e01540a57f8822b2efb8638996873f945 Mon Sep 17 00:00:00 2001 From: Augusto Noronha Date: Tue, 11 May 2021 13:15:03 -0300 Subject: [PATCH] Add null-pointer checks when accessing a TypeSystem's SymbolFile A type system is not guaranteed to have a symbol file. This patch adds null-pointer checks so we don't crash when trying to access a type system's symbol file. Reviewed By: aprantl, teemperor Differential Revision: https://reviews.llvm.org/D101539 --- .../source/Plugins/SymbolFile/PDB/PDBASTParser.cpp | 36 +++++++++++++++++----- .../Plugins/TypeSystem/Clang/TypeSystemClang.cpp | 8 ++--- lldb/source/Symbol/Type.cpp | 3 +- lldb/unittests/Symbol/TestTypeSystemClang.cpp | 12 ++++++++ 4 files changed, 46 insertions(+), 13 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp index bf8753e..a691bbe 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -534,8 +534,12 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { auto type_def = llvm::dyn_cast(&type); assert(type_def); + SymbolFile *symbol_file = m_ast.GetSymbolFile(); + if (!symbol_file) + return nullptr; + lldb_private::Type *target_type = - m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId()); + symbol_file->ResolveTypeUID(type_def->getTypeId()); if (!target_type) return nullptr; @@ -609,8 +613,13 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { auto arg = arg_enum->getChildAtIndex(arg_idx); if (!arg) break; + + SymbolFile *symbol_file = m_ast.GetSymbolFile(); + if (!symbol_file) + return nullptr; + lldb_private::Type *arg_type = - m_ast.GetSymbolFile()->ResolveTypeUID(arg->getSymIndexId()); + symbol_file->ResolveTypeUID(arg->getSymIndexId()); // If there's some error looking up one of the dependent types of this // function signature, bail. if (!arg_type) @@ -621,8 +630,12 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { lldbassert(arg_list.size() <= num_args); auto pdb_return_type = func_sig->getReturnType(); + SymbolFile *symbol_file = m_ast.GetSymbolFile(); + if (!symbol_file) + return nullptr; + lldb_private::Type *return_type = - m_ast.GetSymbolFile()->ResolveTypeUID(pdb_return_type->getSymIndexId()); + symbol_file->ResolveTypeUID(pdb_return_type->getSymIndexId()); // If there's some error looking up one of the dependent types of this // function signature, bail. if (!return_type) @@ -654,10 +667,13 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { if (uint64_t size = array_type->getLength()) bytes = size; + SymbolFile *symbol_file = m_ast.GetSymbolFile(); + if (!symbol_file) + return nullptr; + // If array rank > 0, PDB gives the element type at N=0. So element type // will parsed in the order N=0, N=1,..., N=rank sequentially. - lldb_private::Type *element_type = - m_ast.GetSymbolFile()->ResolveTypeUID(element_uid); + lldb_private::Type *element_type = symbol_file->ResolveTypeUID(element_uid); if (!element_type) return nullptr; @@ -711,7 +727,12 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { case PDB_SymType::PointerType: { auto *pointer_type = llvm::dyn_cast(&type); assert(pointer_type); - Type *pointee_type = m_ast.GetSymbolFile()->ResolveTypeUID( + + SymbolFile *symbol_file = m_ast.GetSymbolFile(); + if (!symbol_file) + return nullptr; + + Type *pointee_type = symbol_file->ResolveTypeUID( pointer_type->getPointeeType()->getSymIndexId()); if (!pointee_type) return nullptr; @@ -719,8 +740,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { if (pointer_type->isPointerToDataMember() || pointer_type->isPointerToMemberFunction()) { auto class_parent_uid = pointer_type->getRawSymbol().getClassParentId(); - auto class_parent_type = - m_ast.GetSymbolFile()->ResolveTypeUID(class_parent_uid); + auto class_parent_type = symbol_file->ResolveTypeUID(class_parent_uid); assert(class_parent_type); CompilerType pointer_ast_type; diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index d1add11..7e037a1 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -9306,11 +9306,11 @@ CompilerType TypeSystemClang::DeclGetFunctionArgumentType(void *opaque_decl, std::vector TypeSystemClang::DeclContextFindDeclByName( void *opaque_decl_ctx, ConstString name, const bool ignore_using_decls) { std::vector found_decls; - if (opaque_decl_ctx) { + SymbolFile *symbol_file = GetSymbolFile(); + if (opaque_decl_ctx && symbol_file) { DeclContext *root_decl_ctx = (DeclContext *)opaque_decl_ctx; std::set searched; std::multimap search_queue; - SymbolFile *symbol_file = GetSymbolFile(); for (clang::DeclContext *decl_context = root_decl_ctx; decl_context != nullptr && found_decls.empty(); @@ -9404,10 +9404,10 @@ uint32_t TypeSystemClang::CountDeclLevels(clang::DeclContext *frame_decl_ctx, clang::DeclContext *child_decl_ctx, ConstString *child_name, CompilerType *child_type) { - if (frame_decl_ctx) { + SymbolFile *symbol_file = GetSymbolFile(); + if (frame_decl_ctx && symbol_file) { std::set searched; std::multimap search_queue; - SymbolFile *symbol_file = GetSymbolFile(); // Get the lookup scope for the decl we're trying to find. clang::DeclContext *parent_decl_ctx = child_decl_ctx->getParent(); diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp index df5dab1..8c67748 100644 --- a/lldb/source/Symbol/Type.cpp +++ b/lldb/source/Symbol/Type.cpp @@ -730,7 +730,8 @@ ModuleSP Type::GetModule() { ModuleSP Type::GetExeModule() { if (m_compiler_type) { SymbolFile *symbol_file = m_compiler_type.GetTypeSystem()->GetSymbolFile(); - return symbol_file->GetObjectFile()->GetModule(); + if (symbol_file) + return symbol_file->GetObjectFile()->GetModule(); } return ModuleSP(); } diff --git a/lldb/unittests/Symbol/TestTypeSystemClang.cpp b/lldb/unittests/Symbol/TestTypeSystemClang.cpp index ef7fc4e..44e72f3 100644 --- a/lldb/unittests/Symbol/TestTypeSystemClang.cpp +++ b/lldb/unittests/Symbol/TestTypeSystemClang.cpp @@ -741,3 +741,15 @@ TEST(TestScratchTypeSystemClang, InferSubASTFromLangOpts) { ScratchTypeSystemClang::IsolatedASTKind::CppModules, ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts)); } + +TEST_F(TestTypeSystemClang, GetExeModuleWhenMissingSymbolFile) { + CompilerType compiler_type = m_ast->GetBasicTypeFromAST(lldb::eBasicTypeInt); + lldb_private::Type t(0, nullptr, ConstString("MyType"), llvm::None, nullptr, + 0, {}, {}, compiler_type, + lldb_private::Type::ResolveState::Full); + // Test that getting the execution module when no type system is present + // is handled gracefully. + ModuleSP module = t.GetExeModule(); + EXPECT_EQ(module.get(), nullptr); +} + -- 2.7.4