Add a verification mechanism to CompilerType.

Badly-written code can combine an unrelated TypeSystem and opaque type
pointer into a CompilerType. This is particularly an issue in
swift-lldb. This patch adds an assertion mechanism that catches these
kinds of mistakes early. Because this is an assertion-only code path
there is not cost for release builds.

Differential Revision: https://reviews.llvm.org/D76011
This commit is contained in:
Adrian Prantl 2020-03-11 10:44:15 -07:00
parent 1e0c540360
commit ea96037186
6 changed files with 35 additions and 1 deletions

View File

@ -39,7 +39,9 @@ public:
///
/// \see lldb_private::TypeSystemClang::GetType(clang::QualType)
CompilerType(TypeSystem *type_system, lldb::opaque_compiler_type_t type)
: m_type(type), m_type_system(type_system) {}
: m_type(type), m_type_system(type_system) {
assert(Verify() && "verification failed");
}
CompilerType(const CompilerType &rhs)
: m_type(rhs.m_type), m_type_system(rhs.m_type_system) {}
@ -380,6 +382,13 @@ public:
}
private:
#ifndef NDEBUG
/// If the type is valid, ask the TypeSystem to verify the integrity
/// of the type to catch CompilerTypes that mix and match invalid
/// TypeSystem/Opaque type pairs.
bool Verify() const;
#endif
lldb::opaque_compiler_type_t m_type = nullptr;
TypeSystem *m_type_system = nullptr;
};

View File

@ -129,6 +129,11 @@ public:
void *other_opaque_decl_ctx) = 0;
// Tests
#ifndef NDEBUG
/// Verify the integrity of the type to catch CompilerTypes that mix
/// and match invalid TypeSystem/Opaque type pairs.
virtual bool Verify(lldb::opaque_compiler_type_t type) = 0;
#endif
virtual bool IsArrayType(lldb::opaque_compiler_type_t type,
CompilerType *element_type, uint64_t *size,

View File

@ -2532,6 +2532,12 @@ ConvertAccessTypeToObjCIvarAccessControl(AccessType access) {
// Tests
#ifndef NDEBUG
bool TypeSystemClang::Verify(lldb::opaque_compiler_type_t type) {
return !type || llvm::isa<clang::Type>(GetQualType(type).getTypePtr());
}
#endif
bool TypeSystemClang::IsAggregateType(lldb::opaque_compiler_type_t type) {
clang::QualType qual_type(RemoveWrappingTypes(GetCanonicalQualType(type)));

View File

@ -495,6 +495,10 @@ public:
// Tests
#ifndef NDEBUG
bool Verify(lldb::opaque_compiler_type_t type) override;
#endif
bool IsArrayType(lldb::opaque_compiler_type_t type,
CompilerType *element_type, uint64_t *size,
bool *is_incomplete) override;

View File

@ -865,6 +865,12 @@ bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data,
return false;
}
#ifndef NDEBUG
bool CompilerType::Verify() const {
return !IsValid() || m_type_system->Verify(m_type);
}
#endif
bool lldb_private::operator==(const lldb_private::CompilerType &lhs,
const lldb_private::CompilerType &rhs) {
return lhs.GetTypeSystem() == rhs.GetTypeSystem() &&

View File

@ -70,6 +70,10 @@ lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
return CreateInstanceHelper(language, nullptr, target);
}
#ifndef NDEBUG
bool TypeSystem::Verify(lldb::opaque_compiler_type_t type) { return true; }
#endif
bool TypeSystem::IsAnonymousType(lldb::opaque_compiler_type_t type) {
return false;
}