diff options
10 files changed, 78 insertions, 29 deletions
diff --git a/lldb/include/lldb/Symbol/ClangASTContext.h b/lldb/include/lldb/Symbol/ClangASTContext.h index 2d2c804eb02..e02e05dd571 100644 --- a/lldb/include/lldb/Symbol/ClangASTContext.h +++ b/lldb/include/lldb/Symbol/ClangASTContext.h @@ -253,6 +253,9 @@ public: &type_fields, bool packed = false); + static bool IsOperator(const char *name, + clang::OverloadedOperatorKind &op_kind); + //------------------------------------------------------------------ // Structure, Unions, Classes //------------------------------------------------------------------ diff --git a/lldb/lit/Expr/Inputs/basic.cpp b/lldb/lit/Expr/Inputs/basic.cpp deleted file mode 100644 index 80a79379a2e..00000000000 --- a/lldb/lit/Expr/Inputs/basic.cpp +++ /dev/null @@ -1,12 +0,0 @@ -class Patatino { -private: - long tinky; - -public: - Patatino(long tinky) { this->tinky = tinky; } -}; - -int main(void) { - Patatino *a = new Patatino(26); - return 0; -} diff --git a/lldb/lit/Expr/TestCallCppSym.test b/lldb/lit/Expr/TestCallCppSym.test deleted file mode 100644 index ac48c6f5160..00000000000 --- a/lldb/lit/Expr/TestCallCppSym.test +++ /dev/null @@ -1,6 +0,0 @@ -# RUN: %cxx %p/Inputs/basic.cpp -g -o %t && %lldb -b -s %s -- %t 2>&1 | FileCheck %s - -breakpoint set --file basic.cpp --line 12 -run -call (int)_Znwm(23) -# CHECK: error: use of undeclared identifier '_Znwm' diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/Makefile b/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/Makefile new file mode 100644 index 00000000000..7d85a3a81f8 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/Makefile @@ -0,0 +1,20 @@ +LEVEL = ../../../make + +CXX_SOURCES = a.cpp b.cpp +CXXFLAGS_NO_DEBUGINFO = -c +CXXFLAGS_DEBUGINFO = -c -g + +all: main + +main: a.o b.o + $(CXX) a.o b.o -o main $(LDFLAGS) + +a.o: a.cpp + $(CXX) $(SRCDIR)/a.cpp $(CXXFLAGS_NO_DEBUGINFO) -o a.o + +b.o: b.cpp + $(CXX) $(SRCDIR)/b.cpp $(CXXFLAGS_DEBUGINFO) -o b.o + +clean: OBJECTS += a.o b.o main + +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/TestOperatorOverload.py b/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/TestOperatorOverload.py new file mode 100644 index 00000000000..0191e08d29f --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/TestOperatorOverload.py @@ -0,0 +1,22 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class TestOperatorOverload(TestBase): + mydir = TestBase.compute_mydir(__file__) + + def test_overload(self): + self.build() + (target, process, thread, + main_breakpoint) = lldbutil.run_to_source_breakpoint(self, + "break here", lldb.SBFileSpec("b.cpp"), exe_name = "main") + frame = thread.GetSelectedFrame() + value = frame.EvaluateExpression("x == nil") + self.assertTrue(str(value.GetError()) + .find("comparison between NULL and non-pointer ('Tinky' and NULL)") + != -1) + self.assertTrue(str(value.GetError()) + .find("invalid operands to binary expression ('Tinky' and 'long')") + != -1) + self.assertFalse(value.GetError().Success()) diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/a.cpp b/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/a.cpp new file mode 100644 index 00000000000..77b2f6ace82 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/a.cpp @@ -0,0 +1,9 @@ +class Patatino { +public: + double _blah; + Patatino(int blah) : _blah(blah) {} +}; + +bool operator==(const Patatino& a, const Patatino& b) { + return a._blah < b._blah; +} diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/b.cpp b/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/b.cpp new file mode 100644 index 00000000000..c0eb29bb79f --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/b.cpp @@ -0,0 +1,10 @@ +class Tinky { +public: + int _meh; + Tinky(int meh) : _meh(meh) {} +}; + +int main(void) { + Tinky x(12); + return 0; // break here +} diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp index 7f031356b3c..b929a052d41 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -2156,6 +2156,18 @@ clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type, log->Printf("Function type wasn't a FunctionProtoType"); } + // If this is an operator (e.g. operator new or operator==), only insert + // the declaration we inferred from the symbol if we can provide the correct + // number of arguments. We shouldn't really inject random decl(s) for + // functions that are analyzed semantically in a special way, otherwise we + // will crash in clang. + clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS; + if (func_proto_type && + ClangASTContext::IsOperator(decl_name.getAsString().c_str(), op_kind)) { + if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount( + false, op_kind, func_proto_type->getNumParams())) + return NULL; + } m_decls.push_back(func_decl); return func_decl; diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp index 093be6c898a..07ff2e97aac 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -2072,15 +2072,6 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, return; } } else if (symbol) { - // Don't insert a generic function decl for C++ symbol names. - // Creating a generic function decl is almost surely going to cause troubles - // as it breaks Clang/Sema invariants and causes crashes in clang while - // we're trying to evaluate the expression. - // This means users can't call C++ functions by mangled name when there - // are no debug info (as it happens for C symbol, e.g. printf()). - if (CPlusPlusLanguage::IsCPPMangledName( - symbol->GetMangled().GetMangledName().GetCString())) - return; fun_address = symbol->GetAddress(); function_decl = context.AddGenericFunDecl(); is_indirect_function = symbol->IsIndirect(); diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index 8cb5a069410..df2d25c8d1e 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -138,8 +138,8 @@ static ClangASTMap &GetASTMap() { return *g_map_ptr; } -static bool IsOperator(const char *name, - clang::OverloadedOperatorKind &op_kind) { +bool ClangASTContext::IsOperator(const char *name, + clang::OverloadedOperatorKind &op_kind) { if (name == nullptr || name[0] == '\0') return false; |