From b448d1bf212219febbb182d00c210bad1bd25e7f Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Sat, 10 Aug 2019 10:56:17 +0000 Subject: [PATCH] [lldb] Fix dynamic_cast by no longer failing on variable without metadata Summary: Our IR rewriting infrastructure currently fails when it encounters a variable which has no metadata associated. This causes dynamic_cast to fail as in this case IRForTarget considers the type info pointers ('@_ZTI...') to be variables without associated metadata. As there are no variables for these internal variables, this is actually not an error and dynamic_cast would work fine if we didn't throw this error. This patch fixes this by removing this diagnostics code. In case we would actually hit a variable that has no metadata (but is supposed to have), we still have the error in the expression log so this shouldn't make it harder to diagnose any missing metadata errors. This patch should fix dynamic_cast and also adds a bunch of test coverage to that language feature. Fixes rdar://10813639 Reviewers: davide, labath Reviewed By: labath Subscribers: friss, labath, abidh, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D65932 llvm-svn: 368511 --- .../test/lang/cpp/dynamic_cast/ExtBase.cpp | 5 +++ .../lldbsuite/test/lang/cpp/dynamic_cast/ExtBase.h | 3 ++ .../lldbsuite/test/lang/cpp/dynamic_cast/Makefile | 3 ++ .../test/lang/cpp/dynamic_cast/TestDynamicCast.py | 3 ++ .../lldbsuite/test/lang/cpp/dynamic_cast/main.cpp | 51 ++++++++++++++++++++++ .../Plugins/ExpressionParser/Clang/IRForTarget.cpp | 8 +--- 6 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/ExtBase.cpp create mode 100644 lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/ExtBase.h create mode 100644 lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/Makefile create mode 100644 lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/TestDynamicCast.py create mode 100644 lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/main.cpp diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/ExtBase.cpp b/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/ExtBase.cpp new file mode 100644 index 0000000..4fde4ec --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/ExtBase.cpp @@ -0,0 +1,5 @@ +#include "ExtBase.h" + +char ExtBase::bar() { + return 'x'; +} diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/ExtBase.h b/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/ExtBase.h new file mode 100644 index 0000000..28e139d --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/ExtBase.h @@ -0,0 +1,3 @@ +class ExtBase { + virtual char bar(); +}; diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/Makefile b/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/Makefile new file mode 100644 index 0000000..e1afdbd --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/Makefile @@ -0,0 +1,3 @@ +LEVEL = ../../../make +CXX_SOURCES := main.cpp ExtBase.cpp +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/TestDynamicCast.py b/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/TestDynamicCast.py new file mode 100644 index 0000000..4c9058c --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/TestDynamicCast.py @@ -0,0 +1,3 @@ +from lldbsuite.test import lldbinline + +lldbinline.MakeInlineTest(__file__, globals(), []) diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/main.cpp b/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/main.cpp new file mode 100644 index 0000000..dd2a07b --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/main.cpp @@ -0,0 +1,51 @@ +#include "ExtBase.h" + +class Base { +public: + virtual char foo() { + return 'b'; + } +}; + +class Derived : public Base { +public: + char foo() override { + return 'd'; + } +}; + +class NonOverrideDerived : public Base { +}; + +class ExtDerived : public ExtBase { +public: + char bar() override { + return 'y'; + } +}; + +int main() { + Derived d; + NonOverrideDerived d2; + Base *b = &d; + Base *real_base = new Base(); + char c = dynamic_cast(b)->foo(); + + ExtDerived ext_d; + ExtBase *ext_b = &ext_d; + ExtBase *ext_real_base = new ExtBase(); + c = dynamic_cast(ext_b)->bar(); + + + return 0; //% self.expect("expression dynamic_cast(b) == (Derived*)b", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(b) == (Base*)b", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(real_base) == nullptr", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(&d) == nullptr", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(real_base) == nullptr", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(&d2) == nullptr", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(&d2) == (NonOverrideDerived *)&d2", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(&ext_d) == nullptr", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(ext_b) == (class ExtDerived*)ext_b", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(ext_real_base) == (class ExtBase*)ext_real_base", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(ext_real_base) == nullptr", substrs = ["bool", " = true"]) +} diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp index 8b526de..29d2bbf 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp @@ -1265,16 +1265,10 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) { clang::NamedDecl *named_decl = DeclForGlobal(global_variable); if (!named_decl) { - if (IsObjCSelectorRef(llvm_value_ptr)) - return true; - - if (!global_variable->hasExternalLinkage()) - return true; - LLDB_LOG(log, "Found global variable \"{0}\" without metadata", global_variable->getName()); - return false; + return true; } llvm::StringRef name(named_decl->getName()); -- 2.7.4