This revision was automatically updated to reflect the committed changes.
Closed by commit rGa5fb2e371ec2: [lldb] Complete return types of CXXMethodDecls
to prevent crashing due to… (authored by teemperor).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D73024/new/
https://reviews.llvm.org/D73024
Files:
lldb/packages/Python/lldbsuite/test/lang/cpp/covariant-return-types/Makefile
lldb/packages/Python/lldbsuite/test/lang/cpp/covariant-return-types/TestCovariantReturnTypes.py
lldb/packages/Python/lldbsuite/test/lang/cpp/covariant-return-types/main.cpp
lldb/source/Symbol/ClangASTImporter.cpp
Index: lldb/source/Symbol/ClangASTImporter.cpp
===================================================================
--- lldb/source/Symbol/ClangASTImporter.cpp
+++ lldb/source/Symbol/ClangASTImporter.cpp
@@ -976,6 +976,25 @@
}
}
+/// Takes a CXXMethodDecl and completes the return type if necessary. This
+/// is currently only necessary for virtual functions with covariant return
+/// types where Clang's CodeGen expects that the underlying records are already
+/// completed.
+static void MaybeCompleteReturnType(ClangASTImporter &importer,
+ CXXMethodDecl *to_method) {
+ if (!to_method->isVirtual())
+ return;
+ QualType return_type = to_method->getReturnType();
+ if (!return_type->isPointerType() && !return_type->isReferenceType())
+ return;
+
+ clang::RecordDecl *rd = return_type->getPointeeType()->getAsRecordDecl();
+ if (!rd)
+ return;
+
+ importer.CompleteTagDecl(rd);
+}
+
void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
clang::Decl *to) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -1121,6 +1140,9 @@
}
}
}
+
+ if (clang::CXXMethodDecl *to_method = dyn_cast<CXXMethodDecl>(to))
+ MaybeCompleteReturnType(m_master, to_method);
}
clang::Decl *
Index: lldb/packages/Python/lldbsuite/test/lang/cpp/covariant-return-types/main.cpp
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/lang/cpp/covariant-return-types/main.cpp
@@ -0,0 +1,40 @@
+struct OtherBase {
+ // Allow checking actual type from the test by giving
+ // this class and the subclass unique values here.
+ virtual const char *value() { return "base"; }
+};
+struct OtherDerived : public OtherBase {
+ const char *value() override { return "derived"; }
+};
+
+// Those have to be globals as they would be completed if they
+// are members (which would make this test always pass).
+OtherBase other_base;
+OtherDerived other_derived;
+
+struct Base {
+ // Function with covariant return type that is same class.
+ virtual Base* getPtr() { return this; }
+ virtual Base& getRef() { return *this; }
+ // Function with covariant return type that is a different class.
+ virtual OtherBase* getOtherPtr() { return &other_base; }
+ virtual OtherBase& getOtherRef() { return other_base; }
+};
+
+struct Derived : public Base {
+ Derived* getPtr() override { return this; }
+ Derived& getRef() override { return *this; }
+ OtherDerived* getOtherPtr() override { return &other_derived; }
+ OtherDerived& getOtherRef() override { return other_derived; }
+};
+
+int main() {
+ Derived derived;
+ Base base;
+ Base *base_ptr_to_derived = &derived;
+ (void)base_ptr_to_derived->getPtr();
+ (void)base_ptr_to_derived->getRef();
+ (void)base_ptr_to_derived->getOtherPtr();
+ (void)base_ptr_to_derived->getOtherRef();
+ return 0; // break here
+}
Index: lldb/packages/Python/lldbsuite/test/lang/cpp/covariant-return-types/TestCovariantReturnTypes.py
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/lang/cpp/covariant-return-types/TestCovariantReturnTypes.py
@@ -0,0 +1,40 @@
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+class TestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(self,"// break here", lldb.SBFileSpec("main.cpp"))
+
+ # Test covariant return types for pointers to class that contains the called function.
+ self.expect_expr("derived.getPtr()", result_type="Derived *")
+ self.expect_expr("base_ptr_to_derived->getPtr()", result_type="Base *")
+ self.expect_expr("base.getPtr()", result_type="Base *")
+ # The same tests with reference types. LLDB drops the reference when it turns the
+ # result into a SBValue so check for the the underlying type of the result.
+ self.expect_expr("derived.getRef()", result_type="Derived")
+ self.expect_expr("base_ptr_to_derived->getRef()", result_type="Base")
+ self.expect_expr("base.getRef()", result_type="Base")
+
+ # Test covariant return types for pointers to class that does *not* contain the called function.
+ self.expect_expr("derived.getOtherPtr()", result_type="OtherDerived *")
+ self.expect_expr("base_ptr_to_derived->getOtherPtr()", result_type="OtherBase *")
+ self.expect_expr("base.getOtherPtr()", result_type="OtherBase *")
+ # The same tests with reference types. LLDB drops the reference when it turns the
+ # result into a SBValue so check for the the underlying type of the result.
+ self.expect_expr("derived.getOtherRef()", result_type="OtherDerived")
+ self.expect_expr("base_ptr_to_derived->getOtherRef()", result_type="OtherBase")
+ self.expect_expr("base.getOtherRef()", result_type="OtherBase")
+
+ # Test that we call the right function and get the right value back.
+ self.expect_expr("derived.getOtherPtr()->value()", result_summary='"derived"')
+ self.expect_expr("base_ptr_to_derived->getOtherPtr()->value()", result_summary='"derived"')
+ self.expect_expr("base.getOtherPtr()->value()", result_summary='"base"')
+ self.expect_expr("derived.getOtherRef().value()", result_summary='"derived"')
+ self.expect_expr("base_ptr_to_derived->getOtherRef().value()", result_summary='"derived"')
+ self.expect_expr("base.getOtherRef().value()", result_summary='"base"')
Index: lldb/packages/Python/lldbsuite/test/lang/cpp/covariant-return-types/Makefile
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/lang/cpp/covariant-return-types/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits