[lldb] Fix UB cast when encountering DW_LANG_* >= eNumLanguageTypes (#150132)

LanguageType has two kinds of enumerators in it. The first is
DWARF-assigned enumerators which must be consecutive and match DW_LANG
values. The second is the vendor-assigned enumerators which must be
unique and must follow on from the DWARF-assigned values (i.e. the first
one is currently eLanguageTypeMojo + 1) even if that collides with
DWARF-assigned values that lldb is not yet aware of

Only the DWARF-assigned enumerators may be static_cast from DW_LANG
since their values match. The vendor-assigned enumerators must be
explicitly converted since their values do not match. This needs to
handle new languages added to DWARF and not yet implemented in lldb.

This fixes a crash when encountering a DW_LANG value >=
eNumLanguageTypes and wrong behaviour when encountering DW_LANG values
that have not yet been added to LanguageType but happen to coincide with
a vendor-assigned enumerator due to the consecutive values requirement
described above.

Another way to fix the crash is to add the language to LanguageType (and
fill any preceeding gaps in the number space) so that the DW_LANG being
encountered is correctly handled but this just moves the problem to a
new subset of DW_LANG values.

Also fix an unnecessary static-cast from LanguageType to LanguageType.
This commit is contained in:
Daniel Sanders
2025-07-22 17:45:13 -07:00
committed by GitHub
parent e0dd22fab1
commit 726502d668
3 changed files with 6 additions and 2 deletions

View File

@@ -518,6 +518,7 @@ enum LanguageType {
eLanguageTypeAssembly = 0x0031,
eLanguageTypeC_sharp = 0x0032,
eLanguageTypeMojo = 0x0033,
eLanguageTypeLastStandardLanguage = eLanguageTypeMojo,
// Vendor Extensions
// Note: Language::GetNameForLanguageType

View File

@@ -4330,13 +4330,16 @@ SymbolFileDWARF::GetContainingDeclContext(const DWARFDIE &die) {
}
LanguageType SymbolFileDWARF::LanguageTypeFromDWARF(uint64_t val) {
if (val <= eLanguageTypeLastStandardLanguage)
return static_cast<LanguageType>(val);
// Note: user languages between lo_user and hi_user must be handled
// explicitly here.
switch (val) {
case DW_LANG_Mips_Assembler:
return eLanguageTypeMipsAssembler;
default:
return static_cast<LanguageType>(val);
return eLanguageTypeUnknown;
}
}

View File

@@ -257,7 +257,7 @@ static uint32_t num_languages =
LanguageType Language::GetLanguageTypeFromString(llvm::StringRef string) {
for (const auto &L : language_names) {
if (string.equals_insensitive(L.name))
return static_cast<LanguageType>(L.type);
return L.type;
}
return eLanguageTypeUnknown;