Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

C++: indirect include plus forward declaration binds one receiver to unrelated duplicate classes

オープン
#2,542 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 2 日以内に返信

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
52/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
cpp, python
領域
devtools

調査の方向性

Run the supplied make_repro.py script, then confirm each generated caller.cpp passes the clang++ check. Index each repository with index_repository using a fresh graph cache or full reindex, and use query_graph with the provided Cypher query to inspect RunProbe's CALLS edges. Done means all four calls target gamma/probe_device.h, or are reported unresolved/ambiguous rather than attributed to unrelated classes.

索引モデルが issue の本文から書いたものです。

説明

cypher parsing/quality windows
Version / platform

Source build on Windows x64, MCP server version dev. Upstream base: 96c3f41cf334d87670cb085f1fcf16f637293222; tested with the narrow direct-include fix in #2541, head 7d3e09baf8b132a140ded36443382a8b54530986. This uses the upstream executable, not a reduced fork. Tested binary SHA-256: f932d8fdb7deb0c19f58bb94b1c6cf914ca1c43a565e705e5b7176ed1f410cd5.

Problem

A valid C++ caller obtains ProbeDevice through an indirect include and then includes a header with a forward declaration of that same class. The graph connects RunProbe to methods from two unrelated same-named classes that are not included in this translation unit. Adding a compilation database with the intended header search path does not prevent these wrong edges in this fixture.

This reports a concrete wrong-target result. It does not assume compiler-equivalent analysis is a promised feature, or establish header-search-path handling as the root cause.

Self-contained synthetic reproduction

Save this as make_repro.py and run python make_repro.py. All identifiers and files below are independently constructed synthetic examples.

from pathlib import Path
import json

base = Path("cpp-indirect-repro")
for case in ("quoted_indirect_forward", "search_path_indirect_forward", "direct_control"):
    repo = base / case
    repo.mkdir(parents=True, exist_ok=True)
    for folder, methods in (("alpha", ("Open", "Close")),
                            ("beta", ("Read", "Write")),
                            ("gamma", ("Open", "Close", "Read", "Write"))):
        (repo / folder).mkdir(exist_ok=True)
        code = "#pragma once\nclass ProbeDevice { public: "
        code += " ".join("int " + m + "() { return 0; }" for m in methods)
        (repo / folder / "probe_device.h").write_text(code + " };\n", encoding="utf-8")
    (repo / "decls.h").write_text("class ProbeDevice;\n", encoding="utf-8")
    bridge = ('#include <probe_device.h>\n' if case.startswith("search")
              else '#include "gamma/probe_device.h"\n')
    (repo / "bridge.h").write_text(bridge, encoding="utf-8")
    includes = ('#include "gamma/probe_device.h"\n' if case == "direct_control"
                else '#include "bridge.h"\n#include "decls.h"\n')
    calls = "void RunProbe(ProbeDevice& dev) { dev.Open(); dev.Close(); dev.Read(); dev.Write(); }\n"
    (repo / "caller.cpp").write_text(includes + calls, encoding="utf-8")
    if case.startswith("search"):
        command = {"directory": str(repo.resolve()),
                   "file": str((repo / "caller.cpp").resolve()),
                   "arguments": ["clang++", "-std=c++17", "-Igamma", "-fsyntax-only", "caller.cpp"]}
        (repo / "compile_commands.json").write_text(json.dumps([command]), encoding="utf-8")

The three directories are separate test repositories. Only the gamma class is visible to the caller; the alpha and beta headers represent unrelated alternatives in the indexed repository.

Inside each generated directory, this compiler check passed:

clang++ -std=c++17 -Igamma -fsyntax-only caller.cpp

For each directory, index its absolute path with index_repository, using a fresh graph cache (or an explicit full reindex). Use the returned project identifier with query_graph:

MATCH (f:Function)-[r:CALLS]->(c)
WHERE f.name = 'RunProbe'
RETURN c.name, c.file_path, r.strategy, r.confidence
LIMIT 20
Expected

All four calls in RunProbe target the methods in gamma/probe_device.h.

If this receiver cannot be resolved within the supported analysis model, an unresolved/ambiguous result would be preferable to attributing the calls to unrelated alternatives. This does not ask for a particular implementation.

Actual

Both quoted_indirect_forward and search_path_indirect_forward produce:

Method Target file Strategy Confidence
Open alpha/probe_device.h suffix_match 0.28
Close alpha/probe_device.h suffix_match 0.28
Read beta/probe_device.h suffix_match 0.28
Write beta/probe_device.h suffix_match 0.28

All four targets are wrong for this translation unit. The search_path_indirect_forward case includes a generated compile_commands.json with -Igamma.

The direct_control case targets gamma/probe_device.h for all four methods, with lsp_base_dispatch / 0.95. The control changes both the include form and the extra forward-declaration include, so it does not isolate either as the sole cause.

Partial-parse and unusable-parse counts were both zero in all three cases. These wrong edges are low-confidence heuristic edges; that limitation is visible, but they still identify unrelated methods as callees.

Related
  • #2541 addresses the narrower direct quoted-include duplicate-receiver case. This reproduction remains incorrect with that patch.
  • #1153 reports instance/pointer call omissions. This report specifically concerns false CALLS targets distributed across duplicate definitions.
  • #1970 requests explicit forward-declaration metadata for Class nodes. This report supplies a concrete call-target reproduction; it does not establish that missing metadata is the sole cause.

No proprietary source, identifiers, absolute machine paths, project-derived IDs or internal logs are included.

主要言語
C
スター
45.8k
フォーク
3.8k
平均マージ
3日 4時間
マージ済み PR(30日)
208

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

DeusData/codebase-memory-mcp のほかの issue

DeusData/codebase-memory-mcp の issue をすべて見る

似ている issue

C の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。