From 746101620732788c5f975ac96f83ad90213e1252 Mon Sep 17 00:00:00 2001 From: Timur Golubovich Date: Tue, 9 Sep 2025 13:39:33 +0000 Subject: [PATCH] [lldb][TypeSystemClang] Added unique builtins types for __bf16 and _Float16 During debugging applization with __bf16 and _Float16 float types it was discovered that lldb creates the same CompilerType for them. This can cause an infinite recursion error, if one tries to create two struct specializations with these types and then inherit one specialization from another. --- .../TypeSystem/Clang/TypeSystemClang.cpp | 8 +++++++ .../floating-types-specialization/Makefile | 3 +++ .../TestCppFloatingTypesSpecialization.py | 22 +++++++++++++++++++ .../floating-types-specialization/main.cpp | 11 ++++++++++ .../TestCppTemplateArguments.py | 2 +- 5 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 lldb/test/API/lang/cpp/floating-types-specialization/Makefile create mode 100644 lldb/test/API/lang/cpp/floating-types-specialization/TestCppFloatingTypesSpecialization.py create mode 100644 lldb/test/API/lang/cpp/floating-types-specialization/main.cpp diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index c4a917f59fb88..4e7d4d26a3493 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -959,6 +959,12 @@ CompilerType TypeSystemClang::GetBuiltinTypeForDWARFEncodingAndBitSize( if (type_name == "long double" && QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleTy)) return GetType(ast.LongDoubleTy); + if (type_name == "__bf16" && + QualTypeMatchesBitSize(bit_size, ast, ast.BFloat16Ty)) + return GetType(ast.BFloat16Ty); + if (type_name == "_Float16" && + QualTypeMatchesBitSize(bit_size, ast, ast.Float16Ty)) + return GetType(ast.Float16Ty); // As Rust currently uses `TypeSystemClang`, match `f128` here as well so it // doesn't get misinterpreted as `long double` on targets where they are // the same size but different formats. @@ -1791,6 +1797,8 @@ bool TypeSystemClang::RecordHasFields(const RecordDecl *record_decl) { for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); base_class != base_class_end; ++base_class) { + assert(record_decl != base_class->getType()->getAsCXXRecordDecl() && + "Base can't inherit from itself."); if (RecordHasFields(base_class->getType()->getAsCXXRecordDecl())) return true; } diff --git a/lldb/test/API/lang/cpp/floating-types-specialization/Makefile b/lldb/test/API/lang/cpp/floating-types-specialization/Makefile new file mode 100644 index 0000000000000..99998b20bcb05 --- /dev/null +++ b/lldb/test/API/lang/cpp/floating-types-specialization/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/lang/cpp/floating-types-specialization/TestCppFloatingTypesSpecialization.py b/lldb/test/API/lang/cpp/floating-types-specialization/TestCppFloatingTypesSpecialization.py new file mode 100644 index 0000000000000..9564a0bc31809 --- /dev/null +++ b/lldb/test/API/lang/cpp/floating-types-specialization/TestCppFloatingTypesSpecialization.py @@ -0,0 +1,22 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestCase(TestBase): + def test(self): + self.build() + lldbutil.run_to_source_breakpoint( + self, "// break here", lldb.SBFileSpec("main.cpp", False) + ) + + self.expect_expr("f0", result_type="Foo<__bf16>") + self.expect_expr("f1", result_type="Foo<__fp16>") + + # Test sizeof to ensure while computing layout we don't do + # infinite recursion. + v = self.frame().EvaluateExpression("sizeof(f0)") + self.assertEqual(v.GetValueAsUnsigned() > 0, True) + v = self.frame().EvaluateExpression("sizeof(f1)") + self.assertEqual(v.GetValueAsUnsigned() > 0, True) diff --git a/lldb/test/API/lang/cpp/floating-types-specialization/main.cpp b/lldb/test/API/lang/cpp/floating-types-specialization/main.cpp new file mode 100644 index 0000000000000..e3e8a3767fef8 --- /dev/null +++ b/lldb/test/API/lang/cpp/floating-types-specialization/main.cpp @@ -0,0 +1,11 @@ +template struct Foo; + +template <> struct Foo<__bf16> {}; + +template <> struct Foo<_Float16> : Foo<__bf16> {}; + +int main() { + Foo<__bf16> f0; + Foo<_Float16> f1; + return 0; // break here +} diff --git a/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py b/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py index eac7b5ef1099a..f26d382bf8582 100644 --- a/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py +++ b/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py @@ -82,7 +82,7 @@ def test(self): value = self.expect_expr("temp7", result_type="Foo<__fp16, __fp16>") self.assertFalse(value.GetType().GetTemplateArgumentValue(target, 1)) - value = self.expect_expr("temp8", result_type="Foo<__fp16, __fp16>") + value = self.expect_expr("temp8", result_type="Foo<__bf16, __bf16>") self.assertFalse(value.GetType().GetTemplateArgumentValue(target, 1)) value = self.expect_expr("temp9", result_type="Bar")