Split out from #1247 per @aznikline's scoping there. #1247 now covers the explicit a.operator+(b) form; this issue tracks the other two cases, which share a root cause: they need receiver type inference.
codegraph version
1.2.0
Cases
For a C++ overloaded operator, no calls edge is recorded into the operator method when it is invoked via:
- infix —
a + b (parses as binary_expression, which isn't in C++'s callTypes, so it's never treated as a call site)
- subscript —
a[i] (parses as subscript_expression, same shape)
Repro (optest.cpp, then codegraph init)
struct V {
int x;
V operator+(const V& o) const { return V{x + o.x}; }
V operator[](int i) const { return V{x + i}; }
int get() const { return x; }
};
int plainCaller(const V& a) { return a.get(); } // edge present (control)
V infixCaller(const V& a, const V& b) { return a + b; } // no edge to operator+
V subscriptCaller(const V& a) { return a[3]; } // no edge to operator[]
SELECT s.name, t.name FROM edges e
JOIN nodes s ON e.source = s.id
JOIN nodes t ON e.target = t.id
WHERE e.kind = 'calls';
Observed: only plainCaller | get; no edge for infixCaller -> operator+ or subscriptCaller -> operator[].
Note
Per @aznikline's analysis in #1247, resolving these needs knowing the receiver's type and that it declares the operator (receiver type inference), which the resolver doesn't do today — and the #1230 discussion flags that route as drift-prone. Filing separately so the contained explicit-form fix (#1247) isn't blocked on it, and so the common real-code form (infix) stays tracked for call-graph consumers.
Split out from #1247 per @aznikline's scoping there. #1247 now covers the explicit
a.operator+(b)form; this issue tracks the other two cases, which share a root cause: they need receiver type inference.codegraph version
1.2.0
Cases
For a C++ overloaded operator, no
callsedge is recorded into the operator method when it is invoked via:a + b(parses asbinary_expression, which isn't in C++'scallTypes, so it's never treated as a call site)a[i](parses assubscript_expression, same shape)Repro (
optest.cpp, thencodegraph init)Observed: only
plainCaller | get; no edge forinfixCaller -> operator+orsubscriptCaller -> operator[].Note
Per @aznikline's analysis in #1247, resolving these needs knowing the receiver's type and that it declares the operator (receiver type inference), which the resolver doesn't do today — and the #1230 discussion flags that route as drift-prone. Filing separately so the contained explicit-form fix (#1247) isn't blocked on it, and so the common real-code form (infix) stays tracked for call-graph consumers.