diff --git a/lldb/test/API/lang/cpp/odr-handling-with-dylib/Makefile b/lldb/test/API/lang/cpp/odr-handling-with-dylib/Makefile new file mode 100644 index 0000000000000..91eadaa37282e --- /dev/null +++ b/lldb/test/API/lang/cpp/odr-handling-with-dylib/Makefile @@ -0,0 +1,6 @@ +CXX_SOURCES := main.cpp service.cpp + +DYLIB_CXX_SOURCES := plugin.cpp +DYLIB_NAME := plugin + +include Makefile.rules diff --git a/lldb/test/API/lang/cpp/odr-handling-with-dylib/TestOdrHandlingWithDylib.py b/lldb/test/API/lang/cpp/odr-handling-with-dylib/TestOdrHandlingWithDylib.py new file mode 100644 index 0000000000000..f67d933f6ae51 --- /dev/null +++ b/lldb/test/API/lang/cpp/odr-handling-with-dylib/TestOdrHandlingWithDylib.py @@ -0,0 +1,29 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class OdrHandlingWithDylibTestCase(TestBase): + @skipIf( + bugnumber="https://github.com/llvm/llvm-project/issues/50375, rdar://135551810" + ) + def test(self): + """ + Tests that the expression evaluator is able to deal with types + whose definitions conflict across multiple LLDB modules (in this + case the definition for 'class Service' in the main executable + has an additional field compared to the definition found in the + dylib). This causes the ASTImporter to detect a name conflict + while importing 'Service'. With LLDB's liberal ODRHandlingType + the ASTImporter happily creates a conflicting AST node for + 'Service' in the scratch ASTContext, leading to a crash down + the line. + """ + self.build() + + lldbutil.run_to_source_breakpoint( + self, "plugin_entry", lldb.SBFileSpec("plugin.cpp") + ) + + self.expect_expr("*gProxyThis") diff --git a/lldb/test/API/lang/cpp/odr-handling-with-dylib/main.cpp b/lldb/test/API/lang/cpp/odr-handling-with-dylib/main.cpp new file mode 100644 index 0000000000000..f3372e0fbe701 --- /dev/null +++ b/lldb/test/API/lang/cpp/odr-handling-with-dylib/main.cpp @@ -0,0 +1,11 @@ +#include "plugin.h" + +#define HIDE_FROM_PLUGIN 1 +#include "service.h" + +int main() { + exported(); + plugin_init(); + plugin_entry(); + return 0; +} diff --git a/lldb/test/API/lang/cpp/odr-handling-with-dylib/plugin.cpp b/lldb/test/API/lang/cpp/odr-handling-with-dylib/plugin.cpp new file mode 100644 index 0000000000000..190388000a3c8 --- /dev/null +++ b/lldb/test/API/lang/cpp/odr-handling-with-dylib/plugin.cpp @@ -0,0 +1,14 @@ +#include "plugin.h" +#include "service.h" + +struct Proxy : public Service { + State *proxyState; +}; + +Proxy *gProxyThis = 0; + +extern "C" { +void plugin_init() { gProxyThis = new Proxy; } + +void plugin_entry() {} +} diff --git a/lldb/test/API/lang/cpp/odr-handling-with-dylib/plugin.h b/lldb/test/API/lang/cpp/odr-handling-with-dylib/plugin.h new file mode 100644 index 0000000000000..9d4ba5df5a83a --- /dev/null +++ b/lldb/test/API/lang/cpp/odr-handling-with-dylib/plugin.h @@ -0,0 +1,9 @@ +#ifndef PLUGIN_H_IN +#define PLUGIN_H_IN + +extern "C" { +void plugin_entry(void); +void plugin_init(void); +} + +#endif // PLUGIN_H_IN diff --git a/lldb/test/API/lang/cpp/odr-handling-with-dylib/service.cpp b/lldb/test/API/lang/cpp/odr-handling-with-dylib/service.cpp new file mode 100644 index 0000000000000..6302a45483495 --- /dev/null +++ b/lldb/test/API/lang/cpp/odr-handling-with-dylib/service.cpp @@ -0,0 +1,15 @@ +#define HIDE_FROM_PLUGIN 1 +#include "service.h" + +struct ServiceAux { + Service *Owner; +}; + +struct Service::State {}; + +void exported() { + // Make sure debug-info for definition of Service is + // emitted in this CU. + Service service; + service.start(0); +} diff --git a/lldb/test/API/lang/cpp/odr-handling-with-dylib/service.h b/lldb/test/API/lang/cpp/odr-handling-with-dylib/service.h new file mode 100644 index 0000000000000..37c6b9aeb2d9b --- /dev/null +++ b/lldb/test/API/lang/cpp/odr-handling-with-dylib/service.h @@ -0,0 +1,20 @@ +#ifndef SERVICE_H_IN +#define SERVICE_H_IN + +struct ServiceAux; + +struct Service { + struct State; + bool start(State *) { return true; } + +#ifdef HIDE_FROM_PLUGIN + int __resv1; +#endif // !HIDE_FROM_PLUGIN + + Service *__owner; + ServiceAux *aux; +}; + +void exported(); + +#endif