Skip to content

Commit b075f05

Browse files
authored
Merge pull request DeusData#633 from DeusData/test/cpp-enclosing-attr-438
test(extract): guard C++ out-of-line method/ctor/dtor enclosing attribution
2 parents 66b3e30 + 4953fca commit b075f05

1 file changed

Lines changed: 58 additions & 0 deletions

File tree

tests/test_extraction.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1812,6 +1812,62 @@ TEST(c_caller_attribution) {
18121812
PASS();
18131813
}
18141814

1815+
/* adc8304 (the dedup refactor bundled into #463) re-pointed the C/C++ enclosing-
1816+
* function resolver at the canonical declarator walker: qualified names (Foo::bar)
1817+
* now resolve via resolve_qualified_name(), and `type_identifier` was dropped from
1818+
* the terminal-name set. These guard that out-of-line C++ method / ctor / dtor
1819+
* definitions still attribute their inner calls to the enclosing function, not the
1820+
* module — i.e. that the dedup did not reintroduce the #438 regression on the
1821+
* qualified-declarator path. Module QN for "m.cpp" under prefix "t" is "t.m". */
1822+
TEST(cpp_out_of_line_method_caller_attribution) {
1823+
CBMFileResult *r = extract("struct Foo { void bar(); };\n"
1824+
"int helper(int x) { return x; }\n"
1825+
"void Foo::bar() { helper(1); }\n",
1826+
CBM_LANG_CPP, "t", "m.cpp");
1827+
ASSERT_NOT_NULL(r);
1828+
ASSERT_FALSE(r->has_error);
1829+
ASSERT_GT(r->calls.count, 0);
1830+
int saw_helper = 0;
1831+
for (int i = 0; i < r->calls.count; i++) {
1832+
if (strcmp(r->calls.items[i].callee_name, "helper") == 0) {
1833+
saw_helper = 1;
1834+
/* enclosing must be the out-of-line method, NOT empty and NOT the module. */
1835+
ASSERT_NOT_NULL(r->calls.items[i].enclosing_func_qn);
1836+
ASSERT_FALSE(strcmp(r->calls.items[i].enclosing_func_qn, "") == 0);
1837+
ASSERT_FALSE(strcmp(r->calls.items[i].enclosing_func_qn, "t.m") == 0);
1838+
}
1839+
}
1840+
ASSERT(saw_helper);
1841+
cbm_free_result(r);
1842+
PASS();
1843+
}
1844+
1845+
/* Out-of-line constructor (Foo::Foo) and destructor (Foo::~Foo) exercise the
1846+
* identifier and destructor_name branches of resolve_qualified_name(). A call
1847+
* inside either must attribute to that special member, not the module. */
1848+
TEST(cpp_out_of_line_ctor_dtor_caller_attribution) {
1849+
CBMFileResult *r = extract("struct Foo { Foo(); ~Foo(); };\n"
1850+
"int helper(int x) { return x; }\n"
1851+
"Foo::Foo() { helper(1); }\n"
1852+
"Foo::~Foo() { helper(2); }\n",
1853+
CBM_LANG_CPP, "t", "m.cpp");
1854+
ASSERT_NOT_NULL(r);
1855+
ASSERT_FALSE(r->has_error);
1856+
ASSERT_GT(r->calls.count, 0);
1857+
int helper_calls = 0;
1858+
for (int i = 0; i < r->calls.count; i++) {
1859+
if (strcmp(r->calls.items[i].callee_name, "helper") == 0) {
1860+
helper_calls++;
1861+
ASSERT_NOT_NULL(r->calls.items[i].enclosing_func_qn);
1862+
ASSERT_FALSE(strcmp(r->calls.items[i].enclosing_func_qn, "") == 0);
1863+
ASSERT_FALSE(strcmp(r->calls.items[i].enclosing_func_qn, "t.m") == 0);
1864+
}
1865+
}
1866+
ASSERT(helper_calls >= 1);
1867+
cbm_free_result(r);
1868+
PASS();
1869+
}
1870+
18151871
/* --- Wolfram parse (simple assignment) --- */
18161872
TEST(wolfram_parse) {
18171873
CBMFileResult *r = extract("x = 42;\ny = x + 1;\n", CBM_LANG_WOLFRAM, "t", "simple.wl");
@@ -3117,6 +3173,8 @@ SUITE(extraction) {
31173173
RUN_TEST(wolfram_call);
31183174
RUN_TEST(wolfram_caller_attribution);
31193175
RUN_TEST(c_caller_attribution);
3176+
RUN_TEST(cpp_out_of_line_method_caller_attribution);
3177+
RUN_TEST(cpp_out_of_line_ctor_dtor_caller_attribution);
31203178
RUN_TEST(wolfram_parse);
31213179
RUN_TEST(wolfram_import);
31223180
RUN_TEST(wolfram_nested_def);

0 commit comments

Comments
 (0)