test(cpp): isolate primitive ref ADL negative and add const-ref coverage

Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/3806db7d-1ec8-4cf4-a4fb-e9a755365d4b
This commit is contained in:
copilot-swe-agent[bot] 2026-05-14 18:06:06 +00:00 • committed by GitHub
parent 9efe1d7c79
commit 094798199b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 26 additions and 9 deletions

View file

@ -72,8 +72,6 @@ export interface CppAdlArgInfo {
/** True when the variable's declarator contained one or more
* `pointer_declarator` wrappers. */
readonly isPointer: boolean;
/** True when the variable's declarator was a `reference_declarator`. */
readonly isReference: boolean;
}
const argInfoBySite = new Map<string, readonly CppAdlArgInfo[]>();

View file

@ -743,7 +743,7 @@ function inferCppCallAdlArgs(callNode: SyntaxNode): CppAdlArgInfo[] {
return out;
}
const EMPTY_ADL_ARG: CppAdlArgInfo = { simpleClassName: '', isPointer: false, isReference: false };
const EMPTY_ADL_ARG: CppAdlArgInfo = { simpleClassName: '', isPointer: false };
function classifyAdlArg(argNode: SyntaxNode): CppAdlArgInfo {
// Literals and primitive-shaped expressions never have associated namespaces.
@ -800,7 +800,6 @@ function lookupAdlIdentifierType(identNode: SyntaxNode): CppAdlArgInfo {
// Function-pointer wrappers (`pointer_declarator > function_declarator`)
// must not contribute ADL associated namespaces.
let isPointer = false;
let isReference = false;
let isFunctionPointer = false;
let inner: SyntaxNode = declarator;
let nameText: string | null = null;
@ -818,7 +817,6 @@ function lookupAdlIdentifierType(identNode: SyntaxNode): CppAdlArgInfo {
continue;
}
if (inner.type === 'reference_declarator' || inner.type === 'rvalue_reference_declarator') {
isReference = true;
// reference_declarator has a single child (the inner declarator).
let next: SyntaxNode | null = null;
for (let j = 0; j < inner.namedChildCount; j++) {
@ -849,7 +847,7 @@ function lookupAdlIdentifierType(identNode: SyntaxNode): CppAdlArgInfo {
if (isFunctionPointer || nameText !== varName) continue;
const simpleClassName = extractAdlSimpleTypeName(typeNode);
return { simpleClassName, isPointer, isReference };
return { simpleClassName, isPointer };
}
return EMPTY_ADL_ARG;
}

View file

@ -7,6 +7,12 @@ namespace app {
record(s);
}
void runConstRef() {
audit::Event e;
const audit::Event& cs = e;
recordConst(cs);
}
void runPrimitiveRef() {
int n = 0;
int& r = n;

View file

@ -2,6 +2,4 @@
namespace audit {
struct Event {};
void record(Event& e);
void note(int& n);
}

View file

@ -0,0 +1,8 @@
#pragma once
#include "audit.h"
namespace audit {
void record(Event& e);
void recordConst(const Event& e);
}

View file

@ -2175,7 +2175,16 @@ describe('C++ ADL — reference arg unwrapping', () => {
const calls = getRelationships(result, 'CALLS');
const recordCalls = calls.filter((c) => c.source === 'runRef' && c.target === 'record');
expect(recordCalls.length).toBe(1);
expect(recordCalls[0].targetFilePath).toContain('audit.h');
expect(recordCalls[0].targetFilePath).toContain('record.h');
});
it('recordConst(cs) where cs is const audit::Event& resolves via ADL', () => {
const calls = getRelationships(result, 'CALLS');
const recordCalls = calls.filter(
(c) => c.source === 'runConstRef' && c.target === 'recordConst',
);
expect(recordCalls.length).toBe(1);
expect(recordCalls[0].targetFilePath).toContain('record.h');
});
it('note(r) where r is int& emits zero CALLS edges (primitive ref)', () => {