Skip to content

Commit dd1a5dd

Browse files
committed
Fix C++ demangler type substitution and prefix handling
- Refactor Meta struct to use DemAstNode for detected_types instead of Name - Change detected_types from Vec(Name) to Vec(DemAstNode) for consistency - Update meta_copy, meta_move, and meta_deinit functions accordingly - Change current_prefix from DemString to DemAstNode - Fix bugs in meta.c: - Remove duplicate 'is_const' assignment in meta_copy_scalars - Fix logic error in append_type (was checking !dem_string_empty, should be dem_string_empty) - Fix append_type to properly append NULL and copy node data - Fix indentation in append_tparam function - Update find_type_index and meta_substitute_type to work with DemAstNode - Simplify rule_prefix_tail in v3.c: - Replace complex backtracking logic with cleaner while-loop approach - Build fully qualified prefix incrementally - Properly update substitution table and current_prefix in each iteration - Fix minor issues: - Add missing semicolon in types.h function declaration - Fix const qualifier in cpdem_get_demangled return type (v2.c) - Fix formatting in v3.c (spacing around 'else') - Update trace_graph.c to use DemAstNode instead of Name - Add test timeout configuration in meson.build for slow tests (cxx_base) to handle large number of test cases with ASAN
1 parent b4d2b9d commit dd1a5dd

File tree

6 files changed

+113
-189
lines changed

6 files changed

+113
-189
lines changed

meson.build

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ if get_option('enable_tests') and not meson.is_subproject()
136136
if get_option('b_sanitize').contains('undefined')
137137
test_dependencies += cc.find_library('ubsan')
138138
endif
139+
# Tests that need longer timeout due to large number of test cases
140+
# (especially when running with sanitizers like ASAN)
141+
slow_tests = ['cxx_base']
142+
139143
foreach test : tests
140144
exe = executable(
141145
'test_@0@'.format(test),
@@ -147,7 +151,11 @@ if get_option('enable_tests') and not meson.is_subproject()
147151
install_rpath : '',
148152
implicit_include_directories : false,
149153
)
150-
test(test, exe)
154+
if test in slow_tests
155+
test(test, exe, timeout : 120)
156+
else
157+
test(test, exe)
158+
endif
151159
endforeach
152160

153161
foreach test : unit_tests

src/cplusplus/meta.c

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ static inline void meta_copy_scalars(Meta *dst, Meta *src) {
1515
dst->is_const = src->is_const;
1616
dst->is_ctor = src->is_ctor;
1717
dst->is_dtor = src->is_dtor;
18-
dst->is_const = src->is_const;
1918
dst->trace = src->trace;
2019
dst->template_idx_start = src->template_idx_start;
2120
dst->last_reset_idx = src->last_reset_idx;
@@ -32,34 +31,46 @@ void meta_deinit(Meta *m) {
3231
return;
3332
}
3433

35-
VecF(Name, deinit)(&m->detected_types);
34+
VecF(DemAstNode, deinit)(&m->detected_types);
3635
VecF(Name, deinit)(&m->template_params);
37-
dem_string_deinit(&m->current_prefix);
36+
DemAstNode_deinit(&m->current_prefix);
3837
memset(m, 0, sizeof(Meta));
3938
}
4039

4140
bool meta_copy(Meta *dst, Meta *src) {
4241
if (!(src && dst && src != dst)) {
4342
return false;
4443
}
44+
4545
meta_copy_scalars(dst, src);
46-
// Copy current_prefix (not included in scalars because it needs cloning)
47-
dem_string_deinit(&dst->current_prefix);
48-
if (src->current_prefix.buf && src->current_prefix.len > 0) {
49-
dem_string_init_clone(&dst->current_prefix, &src->current_prefix);
46+
47+
/* Reset destination dynamic members before cloning */
48+
VecF(DemAstNode, deinit)(&dst->detected_types);
49+
VecF(Name, deinit)(&dst->template_params);
50+
DemAstNode_deinit(&dst->current_prefix);
51+
52+
vec_init(&dst->detected_types);
53+
vec_init(&dst->template_params);
54+
55+
if (!DemAstNode_is_empty(&src->current_prefix)) {
56+
DemAstNode_init_clone(&dst->current_prefix, &src->current_prefix);
57+
} else {
58+
DemAstNode_init(&dst->current_prefix);
5059
}
60+
5161
vec_foreach_ptr(&src->detected_types, n, {
52-
Name new_name = { 0 };
53-
dem_string_init_clone(&new_name.name, &n->name);
54-
new_name.num_parts = n->num_parts;
55-
VecF(Name, append)(&dst->detected_types, &new_name);
62+
DemAstNode cloned = { 0 };
63+
DemAstNode_init_clone(&cloned, n);
64+
VecF(DemAstNode, append)(&dst->detected_types, &cloned);
5665
});
66+
5767
vec_foreach_ptr(&src->template_params, n, {
5868
Name new_name = { 0 };
5969
dem_string_init_clone(&new_name.name, &n->name);
6070
new_name.num_parts = n->num_parts;
6171
VecF(Name, append)(&dst->template_params, &new_name);
6272
});
73+
6374
return true;
6475
}
6576

@@ -68,14 +79,16 @@ void meta_move(Meta *dst, Meta *src) {
6879
return;
6980
}
7081
meta_copy_scalars(dst, src);
71-
// Move current_prefix
72-
dem_string_deinit(&dst->current_prefix);
82+
83+
DemAstNode_deinit(&dst->current_prefix);
7384
dst->current_prefix = src->current_prefix;
74-
src->current_prefix = (DemString){ 0 };
75-
VecF(Name, deinit)(&dst->detected_types);
85+
src->current_prefix = (DemAstNode){ 0 };
86+
87+
VecF(DemAstNode, deinit)(&dst->detected_types);
7688
VecF(Name, deinit)(&dst->template_params);
77-
VecF(Name, move)(&dst->detected_types, &src->detected_types);
89+
VecF(DemAstNode, move)(&dst->detected_types, &src->detected_types);
7890
VecF(Name, move)(&dst->template_params, &src->template_params);
91+
7992
memset(src, 0, sizeof(Meta));
8093
}
8194

@@ -159,7 +172,7 @@ bool is_builtin_type(const char *t) {
159172
* rules.
160173
*/
161174
bool append_type(Meta *m, const DemAstNode *x, bool force_append) {
162-
if (!m || !x || !dem_string_empty(&x->dem)) {
175+
if (!m || !x || dem_string_empty(&x->dem)) {
163176
return false;
164177
}
165178

@@ -205,7 +218,7 @@ bool append_type(Meta *m, const DemAstNode *x, bool force_append) {
205218
});
206219
}
207220

208-
DemAstNode *new_node = VecF(DemAstNode, append)(&m->detected_types, x);
221+
DemAstNode *new_node = VecF(DemAstNode, append)(&m->detected_types, NULL);
209222
DemAstNode_copy(new_node, x);
210223
if (!count_name_parts(&new_node->dem)) {
211224
m->detected_types.length--;
@@ -231,12 +244,12 @@ bool append_tparam(Meta *m, DemString *t) {
231244
UNUSED(vec_reserve(&m->template_params, m->template_params.length + 1));
232245
m->template_params.length += 1;
233246

234-
Name *new_name = vec_end(&m->template_params);
235-
dem_string_init_clone(&new_name->name, t);
236-
if (!count_name_parts(new_name)) {
237-
m->template_params.length--;
238-
return false;
239-
}
247+
Name *new_name = vec_end(&m->template_params);
248+
dem_string_init_clone(&new_name->name, t);
249+
if (!count_name_parts(&new_name->name)) {
250+
m->template_params.length--;
251+
return false;
252+
}
240253

241254
return true;
242255
}
@@ -250,8 +263,8 @@ st64 find_type_index(Meta *m, const char *type_str) {
250263
return -1;
251264
}
252265
for (ut64 i = 0; i < m->detected_types.length; i++) {
253-
Name *dt = vec_ptr_at(&m->detected_types, i);
254-
if (dt && dt->name.buf && !strcmp(dt->name.buf, type_str)) {
266+
DemAstNode *dt = vec_ptr_at(&m->detected_types, i);
267+
if (dt && dt->dem.buf && !strcmp(dt->dem.buf, type_str)) {
255268
return (st64)i;
256269
}
257270
}
@@ -264,9 +277,9 @@ st64 find_type_index(Meta *m, const char *type_str) {
264277
*/
265278
bool meta_substitute_type(Meta *m, ut64 id, DemString *dem) {
266279
if (m->detected_types.length > id) {
267-
Name *type_name = vec_ptr_at(&m->detected_types, id);
268-
if (type_name && type_name->name.buf) {
269-
dem_string_append(dem, type_name->name.buf);
280+
DemAstNode *type_node = vec_ptr_at(&m->detected_types, id);
281+
if (type_node && type_node->dem.buf) {
282+
dem_string_append(dem, type_node->dem.buf);
270283
return true;
271284
}
272285
}

src/cplusplus/trace_graph.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ void trace_graph_output_dot(TraceGraph *graph, const char *filename, Meta *meta)
318318

319319
// Add each detected type
320320
for (size_t i = 0; i < meta->detected_types.length; i++) {
321-
Name *type = vec_ptr_at(&meta->detected_types, i);
321+
DemAstNode *type_node = vec_ptr_at(&meta->detected_types, i);
322322
const char *sub_notation;
323323

324324
if (i == 0) {
@@ -333,13 +333,13 @@ void trace_graph_output_dot(TraceGraph *graph, const char *filename, Meta *meta)
333333

334334
// Escape HTML characters in the type name
335335
char *escaped_name = NULL;
336-
if (type->name.buf && type->name.len > 0) {
337-
size_t escaped_len = type->name.len * 6 + 1; // worst case: all chars become &xxxx;
336+
if (type_node && type_node->dem.buf && type_node->dem.len > 0) {
337+
size_t escaped_len = type_node->dem.len * 6 + 1; // worst case: all chars become &xxxx;
338338
escaped_name = calloc(escaped_len, sizeof(char));
339339
if (escaped_name) {
340-
const char *src = type->name.buf;
340+
const char *src = type_node->dem.buf;
341341
char *dst = escaped_name;
342-
for (size_t j = 0; j < type->name.len && src[j]; j++) {
342+
for (size_t j = 0; j < type_node->dem.len && src[j]; j++) {
343343
switch (src[j]) {
344344
case '<':
345345
strcpy(dst, "&lt;");
@@ -374,7 +374,7 @@ void trace_graph_output_dot(TraceGraph *graph, const char *filename, Meta *meta)
374374
f,
375375
" <TD><FONT FACE=\"Courier\">%s</FONT></TD>\n",
376376
escaped_name ? escaped_name : "(empty)");
377-
fprintf(f, " <TD>%u</TD>\n", type->num_parts);
377+
fprintf(f, " <TD>%u</TD>\n", count_name_parts(&type_node->dem));
378378
fprintf(f, " </TR>\n");
379379

380380
if (escaped_name) {

src/cplusplus/types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ bool meta_substitute_type(Meta *m, ut64 id, DemString *dem);
225225
bool meta_substitute_tparam(Meta *m, ut64 id, DemString *dem);
226226
st64 find_type_index(Meta *m, const char *type_str);
227227

228-
ut32 count_name_parts(const DemString *x)
228+
ut32 count_name_parts(const DemString *x);
229229
bool is_builtin_type(const char *t);
230230

231231
#endif // V3_IMPL_TYPES_H

src/cplusplus/v2.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
// For name mangling scheme for GNU v3 ABI, see
1919
// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-structure
2020

21-
static const char *cpdem_get_demangled(CpDem *dem);
21+
static char *cpdem_get_demangled(CpDem *dem);
2222
static CpDem *cpdem_public_name(CpDem *dem);
2323

2424
/* if base name comes with qualifiers then it's a class */
@@ -219,7 +219,7 @@ char *cpdem_get_demangled(CpDem *dem) {
219219
dem_string_concat(&demangled, &dem->suffix);
220220
}
221221

222-
const char *res = dem_str_ndup(demangled.buf, demangled.len);
222+
char *res = dem_str_ndup(demangled.buf, demangled.len);
223223
dem_string_deinit(&demangled);
224224

225225
return res;

0 commit comments

Comments
 (0)