Merge pull request #633 from DeusData/test/cpp-enclosing-attr-438

test(extract): guard C++ out-of-line method/ctor/dtor enclosing attribution
This commit is contained in:
Martin Vogel
2026-06-25 22:47:19 +02:00
committed by GitHub
+58
View File
@@ -1812,6 +1812,62 @@ TEST(c_caller_attribution) {
PASS();
}
/* adc8304 (the dedup refactor bundled into #463) re-pointed the C/C++ enclosing-
* function resolver at the canonical declarator walker: qualified names (Foo::bar)
* now resolve via resolve_qualified_name(), and `type_identifier` was dropped from
* the terminal-name set. These guard that out-of-line C++ method / ctor / dtor
* definitions still attribute their inner calls to the enclosing function, not the
* module — i.e. that the dedup did not reintroduce the #438 regression on the
* qualified-declarator path. Module QN for "m.cpp" under prefix "t" is "t.m". */
TEST(cpp_out_of_line_method_caller_attribution) {
CBMFileResult *r = extract("struct Foo { void bar(); };\n"
"int helper(int x) { return x; }\n"
"void Foo::bar() { helper(1); }\n",
CBM_LANG_CPP, "t", "m.cpp");
ASSERT_NOT_NULL(r);
ASSERT_FALSE(r->has_error);
ASSERT_GT(r->calls.count, 0);
int saw_helper = 0;
for (int i = 0; i < r->calls.count; i++) {
if (strcmp(r->calls.items[i].callee_name, "helper") == 0) {
saw_helper = 1;
/* enclosing must be the out-of-line method, NOT empty and NOT the module. */
ASSERT_NOT_NULL(r->calls.items[i].enclosing_func_qn);
ASSERT_FALSE(strcmp(r->calls.items[i].enclosing_func_qn, "") == 0);
ASSERT_FALSE(strcmp(r->calls.items[i].enclosing_func_qn, "t.m") == 0);
}
}
ASSERT(saw_helper);
cbm_free_result(r);
PASS();
}
/* Out-of-line constructor (Foo::Foo) and destructor (Foo::~Foo) exercise the
* identifier and destructor_name branches of resolve_qualified_name(). A call
* inside either must attribute to that special member, not the module. */
TEST(cpp_out_of_line_ctor_dtor_caller_attribution) {
CBMFileResult *r = extract("struct Foo { Foo(); ~Foo(); };\n"
"int helper(int x) { return x; }\n"
"Foo::Foo() { helper(1); }\n"
"Foo::~Foo() { helper(2); }\n",
CBM_LANG_CPP, "t", "m.cpp");
ASSERT_NOT_NULL(r);
ASSERT_FALSE(r->has_error);
ASSERT_GT(r->calls.count, 0);
int helper_calls = 0;
for (int i = 0; i < r->calls.count; i++) {
if (strcmp(r->calls.items[i].callee_name, "helper") == 0) {
helper_calls++;
ASSERT_NOT_NULL(r->calls.items[i].enclosing_func_qn);
ASSERT_FALSE(strcmp(r->calls.items[i].enclosing_func_qn, "") == 0);
ASSERT_FALSE(strcmp(r->calls.items[i].enclosing_func_qn, "t.m") == 0);
}
}
ASSERT(helper_calls >= 1);
cbm_free_result(r);
PASS();
}
/* --- Wolfram parse (simple assignment) --- */
TEST(wolfram_parse) {
CBMFileResult *r = extract("x = 42;\ny = x + 1;\n", CBM_LANG_WOLFRAM, "t", "simple.wl");
@@ -3117,6 +3173,8 @@ SUITE(extraction) {
RUN_TEST(wolfram_call);
RUN_TEST(wolfram_caller_attribution);
RUN_TEST(c_caller_attribution);
RUN_TEST(cpp_out_of_line_method_caller_attribution);
RUN_TEST(cpp_out_of_line_ctor_dtor_caller_attribution);
RUN_TEST(wolfram_parse);
RUN_TEST(wolfram_import);
RUN_TEST(wolfram_nested_def);