Commit 51c038da authored by Milian Wolff's avatar Milian Wolff

Return Declaration from FunctionDefinition::definition

This fixes an UB cast when we call this on a ClassFunctionDeclaration
with setDeclarationIsDefinition(true) as shown in this UBSAN report:

```
/home/milian/projects/kf5/src/extragear/kdevelop/kdevelop/kdevplatform/language/duchain/functiondefinition.cpp:93:49: runtime error: downcast of address 0x6060005c72c0 which does not point to an object of type 'FunctionDefinition'
0x6060005c72c0: note: object is of type 'KDevelop::ClassFunctionDeclaration'
 26 02 00 76  f0 06 b1 d3 05 7f 00 00  a0 64 21 00 b0 60 00 00  50 6e 22 00 20 60 00 00  10 2b 01 01
              ^~~~~~~~~~~~~~~~~~~~~~~
              vptr for 'KDevelop::ClassFunctionDeclaration'
    #0 0x7f05d2c5377f in KDevelop::FunctionDefinition::definition(KDevelop::Declaration const*) /home/milian/projects/kf5/src/extragear/kdevelop/kdevelop/kdevplatform/language/duchain/functiondefinition.cpp:93
    #1 0x7f05dddae858 in accept /home/milian/projects/kf5/src/extragear/kdevelop/kdevelop/plugins/clang/duchain/documentfinderhelpers.cpp:63
    #2 0x7f05d2f7e0c2 in KDevelop::DUChainUtils::collectItems(KDevelop::DUContext*, KDevelop::DUChainUtils::DUChainItemFilter&) /home/milian/projects/kf5/src/extragear/kdevelop/kdevelop/kdevplatform/language/duchain/duchainutils.cpp:422
    #3 0x7f05d2f7e4ed in KDevelop::DUChainUtils::collectItems(KDevelop::DUContext*, KDevelop::DUChainUtils::DUChainItemFilter&) /home/milian/projects/kf5/src/extragear/kdevelop/kdevelop/kdevplatform/language/duchain/duchainutils.cpp:432
    #4 0x7f05dddacb36 in duchainBuddyFile /home/milian/projects/kf5/src/extragear/kdevelop/kdevelop/plugins/clang/duchain/documentfinderhelpers.cpp:136
    #5 0x7f05dddb2fcc in DocumentFinderHelpers::potentialBuddies(QUrl const&, bool) /home/milian/projects/kf5/src/extragear/kdevelop/kdevelop/plugins/clang/duchain/documentfinderhelpers.cpp:256
    #6 0x7f05dddb3a5d in DocumentFinderHelpers::sourceForHeader(QString const&) /home/milian/projects/kf5/src/extragear/kdevelop/kdevelop/plugins/clang/duchain/documentfinderhelpers.cpp:272
    #7 0x7f05dda0a7d5 in ClangRefactoring::moveIntoSource(KDevelop::IndexedDeclaration const&) /home/milian/projects/kf5/src/extragear/kdevelop/kdevelop/plugins/clang/codegen/clangrefactoring.cpp:158
    #8 0x563aae0570b3 in TestAssistants::testMoveIntoSource() /home/milian/projects/kf5/src/extragear/kdevelop/kdevelop/plugins/clang/tests/test_assistants.cpp:686
    #9 0x563aae01da1f in TestAssistants::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) plugins/clang/tests/test_assistants_autogen/EWIEGA46WW/moc_test_assistants.cpp:127
    #10 0x7f05c7f8458a in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const (/usr/lib/libQt5Core.so.5+0x2c458a)
    #11 0x7f05df029e96  (/usr/lib/libQt5Test.so.5+0x18e96)
    #12 0x7f05df02a750  (/usr/lib/libQt5Test.so.5+0x19750)
    #13 0x7f05df02ad03  (/usr/lib/libQt5Test.so.5+0x19d03)
    #14 0x7f05df02b1cd in QTest::qRun() (/usr/lib/libQt5Test.so.5+0x1a1cd)
    #15 0x7f05df02b57d in QTest::qExec(QObject*, int, char**) (/usr/lib/libQt5Test.so.5+0x1a57d)
    #16 0x563aae03e824 in main /home/milian/projects/kf5/src/extragear/kdevelop/kdevelop/plugins/clang/tests/test_assistants.cpp:61
    #17 0x7f05c6e72151 in __libc_start_main (/usr/lib/libc.so.6+0x28151)
    #18 0x563aae01d1bd in _start (/home/milian/projects/kf5/build-dbg/extragear/kdevelop/kdevelop-sanitized/bin/test_assistants+0xe41bd)
```
parent fa1c24a3
......@@ -79,7 +79,7 @@ IndexedString fetchImplementationFileForClass(const Declaration& targetClass)
for (Declaration* decl : declarations) {
///@todo check for static variable instantiation as well
if (auto* classFun = dynamic_cast<ClassFunctionDeclaration*>(decl))
if (FunctionDefinition* def = FunctionDefinition::definition(classFun)) {
if (auto* def = FunctionDefinition::definition(classFun)) {
qCDebug(LANGUAGE) << "Definition For declaration in:" << def->url().toUrl();
++implementationsInFile[def->url()];
}
......
......@@ -82,7 +82,7 @@ void FunctionDefinition::setDeclaration(Declaration* declaration)
}
}
FunctionDefinition* FunctionDefinition::definition(const Declaration* decl)
Declaration* FunctionDefinition::definition(const Declaration* decl)
{
ENSURE_CHAIN_READ_LOCKED
if (!decl) {
......@@ -90,13 +90,13 @@ FunctionDefinition* FunctionDefinition::definition(const Declaration* decl)
}
if (decl->isFunctionDeclaration() && decl->isDefinition()) {
return const_cast<FunctionDefinition *>(static_cast<const FunctionDefinition *>(decl));
return const_cast<Declaration*>(decl);
}
const KDevVarLengthArray<IndexedDeclaration> allDefinitions = DUChain::definitions()->definitions(decl->id());
for (const IndexedDeclaration decl : allDefinitions) {
if (decl.data()) ///@todo Find better ways of deciding which definition to use
return dynamic_cast<FunctionDefinition*>(decl.data());
return decl.data();
}
return nullptr;
......
......@@ -65,7 +65,7 @@ public:
*
* \returns the definition matching this declaration, otherwise null if no matching definition has been found.
* */
static FunctionDefinition* definition(const Declaration* decl);
static Declaration* definition(const Declaration* decl);
protected:
FunctionDefinition (const FunctionDefinition& rhs);
......
......@@ -305,7 +305,7 @@ QString AbstractDeclarationNavigationContext::html(bool shorten)
modifyHtml() += QStringLiteral(" ");
//modifyHtml() += "<br />";
if (!dynamic_cast<FunctionDefinition*>(d->m_declaration.data())) {
if (FunctionDefinition* definition = FunctionDefinition::definition(d->m_declaration.data())) {
if (auto* definition = FunctionDefinition::definition(d->m_declaration.data())) {
modifyHtml() += labelHighlight(i18n(" Def.: "));
makeLink(QStringLiteral("%1 :%2").arg(definition->url().toUrl().fileName()).arg(definition->
rangeInCurrentRevision()
......
......@@ -137,11 +137,10 @@ void AdaptSignatureAssistant::textChanged(KTextEditor::Document* doc, const KTex
*/
Declaration* otherSide = nullptr;
auto* definition = dynamic_cast<FunctionDefinition*>(funDecl);
if (definition) {
if (auto* definition = dynamic_cast<FunctionDefinition*>(funDecl)) {
m_editingDefinition = true;
otherSide = definition->declaration();
} else if ((definition = FunctionDefinition::definition(funDecl))) {
} else if (auto* definition = FunctionDefinition::definition(funDecl)) {
m_editingDefinition = false;
otherSide = definition;
}
......
......@@ -60,7 +60,7 @@ public:
if (mode == Header && decl->isFunctionDeclaration()) {
// Search for definitions of our declarations
FunctionDefinition* def = FunctionDefinition::definition(decl);
auto* def = FunctionDefinition::definition(decl);
if (def) {
vote(def->url().toUrl());
}
......
......@@ -161,10 +161,7 @@ void ClassBrowserPlugin::showDefinition(const DeclarationPointer& declaration)
Declaration* decl = declaration.data();
// If it's a function, find the function definition to go to the actual declaration.
if (decl && decl->isFunctionDeclaration()) {
auto* funcDefinition = dynamic_cast<FunctionDefinition*>(decl);
if (funcDefinition == nullptr)
funcDefinition = FunctionDefinition::definition(decl);
if (funcDefinition)
if (auto* funcDefinition = FunctionDefinition::definition(decl))
decl = funcDefinition;
}
......
......@@ -192,7 +192,7 @@ void CTestSuite::loadDeclarations(const IndexedString& document, const KDevelop:
}
qCDebug(CMAKE) << "Found test case function declaration" << function->identifier().toString();
FunctionDefinition* def = FunctionDefinition::definition(decl);
auto* def = FunctionDefinition::definition(decl);
m_declarations[name] = def ? IndexedDeclaration(def) : IndexedDeclaration(function);
}
}
......
......@@ -782,7 +782,7 @@ void ContextBrowserPlugin::addHighlight(View* view, KDevelop::Declaration* decl)
}
}
if (FunctionDefinition* def = FunctionDefinition::definition(decl)) {
if (auto* def = FunctionDefinition::definition(decl)) {
highlights.highlights << def->createRangeMoving();
highlights.highlights.back()->setAttribute(highlightedUseAttribute(view));
highlights.highlights.back()->setZDepth(highlightingZDepth);
......
......@@ -704,7 +704,7 @@ void QuickOpenPlugin::quickOpenDefinition()
IndexedString u = decl->url();
KTextEditor::Cursor c = decl->rangeInCurrentRevision().start();
if (FunctionDefinition* def = FunctionDefinition::definition(decl)) {
if (auto* def = FunctionDefinition::definition(decl)) {
def->activateSpecialization();
u = def->url();
c = def->rangeInCurrentRevision().start();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment