News:

The new Release 25.03 is out! You can download binaries for Windows and many major Linux distros here .

Main Menu

bug: ~XXX is always recognized as a destructor

Started by ollydbg, June 11, 2014, 03:47:08 AM

Previous topic - Next topic

ollydbg

From discussion:
Re: The 24 May 2014 build (9778) is out.


Use the git blame, I found this bug happens in this commit.


Revision: 158fe092f69424861b309078741e38e7bec2c0cc
Author: loaden <loaden@2a5c6006-c6dd-42ca-98ab-0921f2732cef>
Date: 2010-11-2 21:29:18
Message:
* special handle destructor function for 'Goto declaration' and 'Goto implementation'

git-svn-id: http://svn.code.sf.net/p/codeblocks/code/trunk@6813 2a5c6006-c6dd-42ca-98ab-0921f2732cef
----
Modified: src/plugins/codecompletion/codecompletion.cpp




Diff file:

src/plugins/codecompletion/codecompletion.cpp | 60 ++++++++++++++++++++++-----
1 file changed, 49 insertions(+), 11 deletions(-)

diff --git a/src/plugins/codecompletion/codecompletion.cpp b/src/plugins/codecompletion/codecompletion.cpp
index ffef317..a5071f6 100644
--- a/src/plugins/codecompletion/codecompletion.cpp
+++ b/src/plugins/codecompletion/codecompletion.cpp
@@ -645,6 +645,27 @@ void CodeCompletion::BuildMenu(wxMenuBar* menuBar)
         Manager::Get()->GetLogManager()->DebugLog(_T("Could not find Project menu!"));
}

+wxChar GetLastNonWhitespaceChar(cbStyledTextCtrl* control, int position)
+{
+    if (!control)
+        return 0;
+
+    while (--position > 0)
+    {
+        const int style = control->GetStyleAt(position);
+        if (control->IsComment(style))
+            continue;
+
+        const wxChar ch = control->GetCharAt(position);
+        if (ch <= _T(' '))
+            continue;
+
+        return ch;
+    }
+
+    return 0;
+}
+
// invariant : on return true : NameUnderCursor is NOT empty
bool EditorHasNameUnderCursor(wxString& NameUnderCursor, bool& IsInclude)
{
@@ -667,21 +688,14 @@ bool EditorHasNameUnderCursor(wxString& NameUnderCursor, bool& IsInclude)
         }
         else
         {
-            int start = control->WordStartPosition(pos, true);
+            const int start = control->WordStartPosition(pos, true);
             const int end = control->WordEndPosition(pos, true);
             const wxString word = control->GetTextRange(start, end);
             if (!word.IsEmpty())
             {
                 NameUnderCursor.Clear();
-                while (--start > 0)
-                {
-                    const wxChar ch = control->GetCharAt(start);
-                    if (ch <= _T(' '))
-                        continue;
-                    else if (ch == _T('~'))
-                        NameUnderCursor << _T("~");
-                    break;
-                }
+                if (GetLastNonWhitespaceChar(control, start) == _T('~'))
+                    NameUnderCursor << _T('~');
                 NameUnderCursor << word;
                 ReturnValue = true;
                 IsInclude = false;
@@ -2573,7 +2587,12 @@ void CodeCompletion::OnGotoDeclaration(wxCommandEvent& event)
     const int pos = editor->GetControl()->GetCurrentPos();
     const int start = editor->GetControl()->WordStartPosition(pos, true);
     const int end = editor->GetControl()->WordEndPosition(pos, true);
-    const wxString target = editor->GetControl()->GetTextRange(start, end);
+    wxString target;
+    if (GetLastNonWhitespaceChar(editor->GetControl(), start) == _T('~'))
+        target << _T('~');
+    target << editor->GetControl()->GetTextRange(start, end);
+    if (target.IsEmpty())
+        return;

     // prepare a boolean filter for declaration/implementation
     bool isDecl = event.GetId() == idGotoDeclaration || event.GetId() == idMenuGotoDeclaration;
@@ -2583,6 +2602,25 @@ void CodeCompletion::OnGotoDeclaration(wxCommandEvent& event)
     TokenIdxSet result;
     m_NativeParser.MarkItemsByAI(result, true, false, true, end);

+    // special handle destructor function
+    if (target[0] == _T('~'))
+    {
+        TokenIdxSet tmp = result;
+        result.clear();
+
+        TokensTree* tokens = m_NativeParser.GetParser().GetTokens();
+        for (TokenIdxSet::iterator it = tmp.begin(); it != tmp.end(); ++it)
+        {
+            Token* tk = tokens->at(*it);
+            if (tk && tk->m_TokenKind == tkClass)
+            {
+                tk = tokens->at(tokens->TokenExists(target, tk->GetSelf(), tkDestructor));
+                if (tk)
+                    result.insert(tk->GetSelf());
+            }
+        }
+    }
+
     // one match
     Token* token = NULL;
     if (result.size() == 1)



Issue:

+    if (GetLastNonWhitespaceChar(editor->GetControl(), start) == _T('~'))
+        target << _T('~');

Maybe, this is the bug.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

damorin

Hi,

sounds exactly like it.

Adding a check for C++ project (or file) should be enough to fix it.

One problem at a time and we will get there.

ollydbg

#2
Quote from: damorin on June 11, 2014, 07:11:42 PM
Hi,

sounds exactly like it.

Adding a check for C++ project (or file) should be enough to fix it.


Hi, ~ can either be logic operator or the destructor prefix, so, why do you think adding a check for C++ project can solve this?
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

damorin

Quote from: ollydbg on June 12, 2014, 06:18:50 AM
Quote from: damorin on June 11, 2014, 07:11:42 PM
Hi,

sounds exactly like it.

Adding a check for C++ project (or file) should be enough to fix it.


Hi, ~ can either be logic operator or the destructor prefix, so, why do you think adding a check for C++ project can solve this?

Oops, that would only fix it in C but the problem would remain in C++. It's not that good then unless there is a check to see if it's a destructor or not.



One problem at a time and we will get there.

Huki

Quote from: ollydbg on June 11, 2014, 03:47:08 AM
From discussion:
Re: The 24 May 2014 build (9778) is out.

Use the git blame, I found this bug happens in this commit.

...


Hi,
Have to remind you that I posted a patch for this one several weeks ago. :) See here.

ollydbg

Quote from: Huki on June 13, 2014, 08:58:46 PM
Quote from: ollydbg on June 11, 2014, 03:47:08 AM
From discussion:
Re: The 24 May 2014 build (9778) is out.

Use the git blame, I found this bug happens in this commit.

...


Hi,
Have to remind you that I posted a patch for this one several weeks ago. :) See here.

Dear Huki, sorry for the delay, I focus my major spare time on other part of CC, and forget your patch.
Now, the patch is in trunk (rev 9794), thanks for your contribution.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.