Closed Bug 1833695 Opened 2 years ago Closed 9 months ago

"Go to definition" may not appear in context menu for templated functions because of duplicate "def" target records

Categories

(Webtools :: Searchfox, defect)

defect

Tracking

(firefox133 fixed)

RESOLVED FIXED
Tracking Status
firefox133 --- fixed

People

(Reporter: botond, Assigned: nicolas.guichard)

References

(Blocks 1 open bug)

Details

Attachments

(2 files)

STR

  1. Go to https://searchfox.org/mozilla-central/source/widget/Theme.cpp#1080
  2. Click on DoDrawWidgetBackground
  3. Observe that the first item in the context menu is "go to declaration", and there is no "go to definition" item
  4. Perform "search" (second context menu item) and observe that the results include the function's definition

Expected results

If searchfox knows where the function's definition is, the context menu includes an item to navigate to it.

The problem seems to be that there are 2 definition records (as accessed from the raw-analysis for Theme.cpp), one with a context/contextsym and one without:

{"loc":"01118:12-34","target":1,"kind":"def","pretty":"mozilla::widget::Theme::DoDrawWidgetBackground","sym":"_ZN7mozilla6widget5Theme22DoDrawWidgetBackgroundERT_P8nsIFrameNS_15StyleAppearanceERK6nsRectN8nsITheme12DrawOverflowE","context":"mozilla::widget::Theme::DoDrawWidgetBackground","contextsym":"_ZN7mozilla6widget5Theme22DoDrawWidgetBackgroundERT_P8nsIFrameNS_15StyleAppearanceERK6nsRectN8nsITheme12DrawOverflowE","peekRange":"1118-1122"}
{"loc":"01118:12-34","target":1,"kind":"def","pretty":"mozilla::widget::Theme::DoDrawWidgetBackground","sym":"_ZN7mozilla6widget5Theme22DoDrawWidgetBackgroundERT_P8nsIFrameNS_15StyleAppearanceERK6nsRectN8nsITheme12DrawOverflowE","peekRange":"1118-1122"}

The jumpref heuristics only emit a definition if there is a single definition, but this is technically 2 definitions. The "search" endpoint only shows one of them because of its suppression logic. (And as noted, we don't currently try and merge target records, just suppress exactly identical versions.)

It seems like the reported contextsym may be the symbol itself, which seems like a bug.

Summary: "Do to declaration" offered instead of "go to definition" when definition is known → "Go to definition" may not appear in context menu for templated functions because of duplicate "def" target records

Note that this seems to happen almost everytime, the specific symbol reported is just one specific one to get a bug going with a specific case.

(In reply to Timothy Nikkel (:tnikkel) from comment #2)

Note that this seems to happen almost everytime, the specific symbol reported is just one specific one to get a bug going with a specific case.

I assume you mean almost every time a templated function is targeted, as opposed to all functions.

Hmm, maybe you are correct. I might just be remembering the times it does not work and forgetting the ones when it does.

Reduced testcase:

struct Theme {
  void CreateWebRenderCommandsForWidget() {
    DoDrawWidgetBackground(0);
  }

  template <typename T>
  void DoDrawWidgetBackground(T);
};

template <typename T>
void Theme::DoDrawWidgetBackground(T) {}
Blocks: 1905433

I've tracked this down to TraverseFunctionDecl and friends calling TraverseFunctionDecl for the definition with a wrong CurDeclContext when traversing templated code. For instance:

   1   │ struct Theme {
   2   │   void CreateWebRenderCommandsForWidget() {
   3   │     DoDrawWidgetBackground(0);
   4   │   }
   5   │ 
   6   │   template <typename T>
   7   │   void DoDrawWidgetBackground(T); // ← when traversing this CXXMethodDecl, we call TraverseFunctionDecl for the definition below, but CurDeclContext == Theme::DoDrawWidgetBackground
   8   │ };
   9   │ 
  10   │ template <typename T>
  11   │ void Theme::DoDrawWidgetBackground(T) {} // ← TraverseCXXMethodDecl is called again here, with CurDeclContext == nullptr
  12   │ 

Resetting the CurDeclContext before the TraverseFunctionDecl calls (and setting it back after) seems to fix the issue. I don't think this can fail, because out-of-line member function definitions can't be nested in another struct/class/function definition.

I'll send a Mozsearch PR for this later this week.

Assignee: nobody → nicolas.guichard
Status: NEW → ASSIGNED
Attached file GitHub Pull Request

Without this, OutOfLineTemplateShouldntHaveContextSym had two
definition target records that disagreed on the contextsym:

  1. The first one was generated when traversing the declaration, because
    it forwards to the definition if out-of-line (see comment in
    TraverseFunctionDecl).
    We didn't reset CurDeclContext, so it looked as-if the definition
    appeared inside the declaration, leading to a bogus contextsym
    (pointing to the function itself).
  2. The second one was generated later on when traversing the definition
    itself. This one had a correct contextsym (ie. none).

This introduces a ValueRollback helper to make sure we don't forget to
rollback CurDeclContext afterwards. (inspired by QScopedValueRollback)

See https://github.com/mozsearch/mozsearch/pull/820

Pushed by bugmail@asutherland.org: https://hg.mozilla.org/integration/autoland/rev/1f2d76d7c0f1 Reset DeclContext stack when analysing out-of-line templated function. r=asuth
Status: ASSIGNED → RESOLVED
Closed: 9 months ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: