Fix some of the Coverity issues in types and analysis code (#1474)
* Fix CID 354663 * Fix CID 352572 * Fix CID 352560 * Fix CID 352557 * Fix CID 352537 * Fix CID 352536 * Fix CID 352490 * Fix CID 352488 * Fix CID 352486 * Fix CID 352484 * Fix CID 352480 * Fix CID 352475 * Fix CID 352471 * Fix CID 352464 * Fix CID 352461 * Fix CID 352455 * Fix CID 352452 * Fix CID 352448
This commit is contained in:
parent
92b7e9321a
commit
3d9baa149d
10 changed files with 136 additions and 91 deletions
|
|
@ -2495,6 +2495,7 @@ RZ_API RZ_OWN RzCallable *rz_analysis_function_derive_type(RzAnalysis *analysis,
|
|||
if (!shortname) {
|
||||
shortname = strdup(f->name);
|
||||
}
|
||||
// At this point the `callable` pointer is *borrowed*
|
||||
RzCallable *callable = rz_type_func_get(analysis->typedb, shortname);
|
||||
free(shortname);
|
||||
if (callable) {
|
||||
|
|
@ -2505,6 +2506,8 @@ RZ_API RZ_OWN RzCallable *rz_analysis_function_derive_type(RzAnalysis *analysis,
|
|||
}
|
||||
// If there is no match - create a new one.
|
||||
// TODO: Figure out if we should use shortname or a fullname here
|
||||
// At this point the `callable` pointer is *owned*
|
||||
// This means we have to free it after
|
||||
callable = rz_type_func_new(analysis->typedb, f->name, NULL);
|
||||
if (!callable) {
|
||||
return NULL;
|
||||
|
|
@ -2528,11 +2531,13 @@ RZ_API RZ_OWN RzCallable *rz_analysis_function_derive_type(RzAnalysis *analysis,
|
|||
RzType *cloned_type = rz_type_clone(var->type);
|
||||
if (!cloned_type) {
|
||||
rz_pvector_free(args);
|
||||
rz_type_callable_free(callable);
|
||||
return NULL;
|
||||
}
|
||||
RzCallableArg *arg = rz_type_callable_arg_new(analysis->typedb, var->name, cloned_type);
|
||||
if (!arg) {
|
||||
rz_pvector_free(args);
|
||||
rz_type_callable_free(callable);
|
||||
return NULL;
|
||||
}
|
||||
rz_type_callable_arg_add(callable, arg);
|
||||
|
|
|
|||
|
|
@ -840,6 +840,7 @@ RZ_API RZ_NULLABLE RzAnalysisVar *rz_serialize_analysis_var_load(RZ_NONNULL RzAn
|
|||
RzType *vartype = rz_type_parse_string_single(fcn->analysis->typedb->parser, type, &error_msg);
|
||||
if (error_msg) {
|
||||
eprintf("Fail to parse the function variable (\"%s\") type: %s\n", name, type);
|
||||
RZ_FREE(error_msg);
|
||||
goto beach;
|
||||
}
|
||||
ret = rz_analysis_function_set_var(fcn, delta, kind, vartype, 0, arg, name);
|
||||
|
|
@ -1011,9 +1012,9 @@ static bool global_var_load_cb(void *user, const char *k, const char *v) {
|
|||
RzType *vartype = rz_type_parse_string_single(ctx->analysis->typedb->parser, type, &error_msg);
|
||||
if (error_msg) {
|
||||
eprintf("Fail to parse the function variable (\"%s\") type: %s\n", name, type);
|
||||
RZ_FREE(error_msg);
|
||||
goto beach;
|
||||
}
|
||||
RZ_FREE(error_msg);
|
||||
RzCore *core = ctx->analysis->core;
|
||||
addr = rz_num_math(core->num, addr_s);
|
||||
glob = rz_analysis_var_global_new(name, addr);
|
||||
|
|
@ -1548,11 +1549,12 @@ RZ_API bool rz_serialize_analysis_xrefs_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAn
|
|||
RZ_API void rz_serialize_analysis_meta_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis) {
|
||||
rz_serialize_spaces_save(sdb_ns(db, "spaces", true), &analysis->meta_spaces);
|
||||
|
||||
PJ *j = pj_new();
|
||||
if (!j) {
|
||||
if (rz_interval_tree_empty(&analysis->meta)) {
|
||||
return;
|
||||
}
|
||||
if (rz_interval_tree_empty(&analysis->meta)) {
|
||||
|
||||
PJ *j = pj_new();
|
||||
if (!j) {
|
||||
return;
|
||||
}
|
||||
char key[0x20];
|
||||
|
|
@ -1560,11 +1562,13 @@ RZ_API void rz_serialize_analysis_meta_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAna
|
|||
RzAnalysisMetaItem *meta;
|
||||
ut64 addr = 0;
|
||||
size_t count = 0;
|
||||
|
||||
#define FLUSH \
|
||||
pj_end(j); \
|
||||
if (snprintf(key, sizeof(key), "0x%" PFMT64x, addr) >= 0) { \
|
||||
sdb_set(db, key, pj_string(j), 0); \
|
||||
}
|
||||
|
||||
rz_interval_tree_foreach (&analysis->meta, it, meta) {
|
||||
RzIntervalNode *node = rz_interval_tree_iter_get(&it);
|
||||
if (count && node->start != addr) {
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ RZ_API RzList *rz_sign_fcn_types(RzAnalysis *a, RzAnalysisFunction *fcn) {
|
|||
}
|
||||
if (!callable->args || rz_pvector_empty(callable->args)) {
|
||||
rz_list_append(ret, rz_str_newf("func.%s.args=0", fcn->name));
|
||||
rz_type_callable_free(callable);
|
||||
return ret;
|
||||
}
|
||||
int fcnargs = rz_pvector_len(callable->args);
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ static void var_type_set_str(RzAnalysis *analysis, RzAnalysisVar *var, const cha
|
|||
RzType *realtype = rz_type_parse_string_single(analysis->typedb->parser, type, &error_msg);
|
||||
if (!realtype && error_msg) {
|
||||
eprintf("Fail to parse type \"%s\":\n%s\n", type, error_msg);
|
||||
free(error_msg);
|
||||
return;
|
||||
}
|
||||
var_type_set(analysis, var, realtype, ref);
|
||||
|
|
|
|||
|
|
@ -1234,6 +1234,7 @@ static int var_cmd(RzCore *core, const char *str) {
|
|||
if (!ttype || error_msg) {
|
||||
eprintf("Can't parse type: \"%s\"\n%s\n", type, error_msg);
|
||||
free(ostr);
|
||||
free(error_msg);
|
||||
return false;
|
||||
}
|
||||
rz_analysis_var_set_type(v1, ttype);
|
||||
|
|
@ -9118,6 +9119,7 @@ RZ_IPI RzCmdStatus rz_analysis_function_signature_type_handler(RzCore *core, int
|
|||
RzType *ret_type = rz_type_parse_string_single(core->analysis->typedb->parser, argv[1], &error_msg);
|
||||
if (!ret_type || error_msg) {
|
||||
eprintf("Cannot parse type \"%s\":\n%s\n", argv[1], error_msg);
|
||||
free(error_msg);
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
if (!rz_type_func_ret_set(core->analysis->typedb, fcn->name, ret_type)) {
|
||||
|
|
@ -9446,6 +9448,7 @@ RZ_IPI RzCmdStatus rz_analysis_function_vars_type_handler(RzCore *core, int argc
|
|||
RzType *v_type = rz_type_parse_string_single(core->analysis->typedb->parser, argv[2], &error_msg);
|
||||
if (!v_type || error_msg) {
|
||||
eprintf("Cannot parse type \"%s\":\n%s\n", argv[2], error_msg);
|
||||
free(error_msg);
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
rz_analysis_var_set_type(v, v_type);
|
||||
|
|
@ -9575,6 +9578,7 @@ RZ_IPI RzCmdStatus rz_analysis_function_vars_bp_handler(RzCore *core, int argc,
|
|||
RzType *var_type = rz_type_parse_string_single(core->analysis->typedb->parser, vartype, &error_msg);
|
||||
if (!var_type || error_msg) {
|
||||
eprintf("Cannot parse type \"%s\":\n%s\n", vartype, error_msg);
|
||||
free(error_msg);
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
rz_analysis_function_set_var(fcn, delta, RZ_ANALYSIS_VAR_KIND_BPV, var_type, 4, isarg, varname);
|
||||
|
|
@ -9679,6 +9683,7 @@ RZ_IPI RzCmdStatus rz_analysis_function_vars_sp_handler(RzCore *core, int argc,
|
|||
RzType *var_type = rz_type_parse_string_single(core->analysis->typedb->parser, vartype, &error_msg);
|
||||
if (!var_type || error_msg) {
|
||||
eprintf("Cannot parse type \"%s\":\n%s\n", vartype, error_msg);
|
||||
free(error_msg);
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
rz_analysis_function_set_var(fcn, delta, RZ_ANALYSIS_VAR_KIND_SPV, var_type, 4, isarg, varname);
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ static void types_xrefs(RzCore *core, const char *typestr) {
|
|||
if (!type || error_msg) {
|
||||
if (error_msg) {
|
||||
eprintf("%s", error_msg);
|
||||
free(error_msg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -260,6 +261,7 @@ static void types_xrefs_all(RzCore *core) {
|
|||
rz_list_push(types_list, strdup(ident));
|
||||
}
|
||||
}
|
||||
rz_list_free(types);
|
||||
}
|
||||
RzList *uniq_types = rz_list_uniq(types_list, (RzListComparator)strcmp);
|
||||
rz_list_free(types_list);
|
||||
|
|
|
|||
|
|
@ -918,12 +918,13 @@ RZ_IPI void rz_core_types_link_print(RzCore *core, RzType *type, ut64 addr, RzOu
|
|||
rz_cons_printf("tl \"%s\" 0x%" PFMT64x "\n", typestr, addr);
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_LONG: {
|
||||
const char *fmt = rz_type_as_format(core->analysis->typedb, type);
|
||||
char *fmt = rz_type_as_format(core->analysis->typedb, type);
|
||||
if (!fmt) {
|
||||
eprintf("Can't fint type %s", typestr);
|
||||
}
|
||||
rz_cons_printf("(%s)\n", typestr);
|
||||
rz_core_cmdf(core, "pf %s @ 0x%" PFMT64x "\n", fmt, addr);
|
||||
free(fmt);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
@ -961,12 +962,13 @@ RZ_IPI void rz_core_types_link_print_all(RzCore *core, RzOutputMode mode) {
|
|||
}
|
||||
|
||||
RZ_IPI void rz_core_types_link(RzCore *core, const char *typestr, ut64 addr) {
|
||||
char *error_msg;
|
||||
char *error_msg = NULL;
|
||||
RzType *type = rz_type_parse_string_single(core->analysis->typedb->parser, typestr, &error_msg);
|
||||
if (!type || error_msg) {
|
||||
if (error_msg) {
|
||||
eprintf("%s", error_msg);
|
||||
}
|
||||
free(error_msg);
|
||||
return;
|
||||
}
|
||||
rz_analysis_type_set_link(core->analysis, type, addr);
|
||||
|
|
|
|||
|
|
@ -1791,7 +1791,7 @@ static int rz_type_format_struct(const RzTypeDB *typedb, RzPrint *p, RzStrBuf *o
|
|||
fmt = rz_type_format(typedb, name);
|
||||
}
|
||||
}
|
||||
if (!fmt || !*fmt) {
|
||||
if (RZ_STR_ISEMPTY(fmt)) {
|
||||
eprintf("Undefined struct '%s'.\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2857,13 +2857,14 @@ static void base_type_to_format_unfold(const RzTypeDB *typedb, RZ_NONNULL RzBase
|
|||
base_type_to_format_no_unfold(typedb, btyp, memb->name, format, fields);
|
||||
}
|
||||
} else {
|
||||
const char *membfmt = rz_type_as_format(typedb, memb->type);
|
||||
char *membfmt = rz_type_as_format(typedb, memb->type);
|
||||
rz_strbuf_append(format, membfmt);
|
||||
if (!rz_type_is_atomic(typedb, memb->type)) {
|
||||
rz_strbuf_appendf(fields, "(%s)%s ", membtype, memb->name);
|
||||
} else {
|
||||
rz_strbuf_appendf(fields, "%s ", memb->name);
|
||||
}
|
||||
free(membfmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2989,15 +2990,15 @@ RZ_API RZ_OWN char *rz_type_as_format(const RzTypeDB *typedb, RZ_NONNULL RzType
|
|||
if (type->kind == RZ_TYPE_KIND_CALLABLE) {
|
||||
// We can't print anything useful for function type
|
||||
// Thus we consider this is just a `void *` pointer
|
||||
return "p";
|
||||
return strdup("p");
|
||||
}
|
||||
// Special case of callable ptr or `void *`
|
||||
if (rz_type_is_void_ptr(type) || rz_type_is_callable_ptr(type)) {
|
||||
return "p";
|
||||
return strdup("p");
|
||||
}
|
||||
// Special case of `char *`
|
||||
if (rz_type_is_char_ptr(type)) {
|
||||
return "z";
|
||||
return strdup("z");
|
||||
}
|
||||
RzStrBuf *buf = rz_strbuf_new(NULL);
|
||||
type_to_format(typedb, buf, type);
|
||||
|
|
|
|||
|
|
@ -178,19 +178,22 @@ static int type_parse_string(CParserState *state, const char *code, char **error
|
|||
|
||||
// If there were errors during the parser then the result is different from 0
|
||||
if (result) {
|
||||
const char *error_msgs = rz_strbuf_drain_nofree(state->errors);
|
||||
char *error_msgs = rz_strbuf_drain_nofree(state->errors);
|
||||
RZ_LOG_DEBUG("Errors:\n");
|
||||
RZ_LOG_DEBUG("%s", error_msgs);
|
||||
const char *warning_msgs = rz_strbuf_drain_nofree(state->warnings);
|
||||
char *warning_msgs = rz_strbuf_drain_nofree(state->warnings);
|
||||
RZ_LOG_DEBUG("Warnings:\n");
|
||||
RZ_LOG_DEBUG("%s", warning_msgs);
|
||||
if (error_msg) {
|
||||
*error_msg = strdup(error_msgs);
|
||||
}
|
||||
free(error_msgs);
|
||||
free(warning_msgs);
|
||||
}
|
||||
if (state->verbose) {
|
||||
const char *debug_msgs = rz_strbuf_drain_nofree(state->debug);
|
||||
char *debug_msgs = rz_strbuf_drain_nofree(state->debug);
|
||||
RZ_LOG_DEBUG("%s", debug_msgs);
|
||||
free(debug_msgs);
|
||||
}
|
||||
|
||||
// After everything parsed, we should preserve the base type database
|
||||
|
|
@ -221,13 +224,16 @@ RZ_API int rz_type_parse_string_stateless(RzTypeParser *parser, const char *code
|
|||
*/
|
||||
RZ_API int rz_type_parse_file_stateless(RzTypeParser *parser, const char *path, const char *dir, char **error_msg) {
|
||||
size_t read_bytes = 0;
|
||||
const char *source_code = rz_file_slurp(path, &read_bytes);
|
||||
char *source_code = rz_file_slurp(path, &read_bytes);
|
||||
if (!source_code || !read_bytes) {
|
||||
free(source_code);
|
||||
return -1;
|
||||
}
|
||||
ut64 file_size = rz_file_size(path);
|
||||
RZ_LOG_DEBUG("File size is %" PFMT64d " bytes, read %zu bytes\n", file_size, read_bytes);
|
||||
return rz_type_parse_string_stateless(parser, source_code, error_msg);
|
||||
int result = rz_type_parse_string_stateless(parser, source_code, error_msg);
|
||||
free(source_code);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -240,13 +246,16 @@ RZ_API int rz_type_parse_file_stateless(RzTypeParser *parser, const char *path,
|
|||
*/
|
||||
RZ_API int rz_type_parse_file(RzTypeDB *typedb, const char *path, const char *dir, char **error_msg) {
|
||||
size_t read_bytes = 0;
|
||||
const char *source_code = rz_file_slurp(path, &read_bytes);
|
||||
char *source_code = rz_file_slurp(path, &read_bytes);
|
||||
if (!source_code || !read_bytes) {
|
||||
free(source_code);
|
||||
return -1;
|
||||
}
|
||||
ut64 file_size = rz_file_size(path);
|
||||
RZ_LOG_DEBUG("File size is %" PFMT64d " bytes, read %zu bytes\n", file_size, read_bytes);
|
||||
return rz_type_parse_string(typedb, source_code, error_msg);
|
||||
int result = rz_type_parse_string(typedb, source_code, error_msg);
|
||||
free(source_code);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -351,15 +360,17 @@ RZ_API RZ_OWN RzType *rz_type_parse_string_single(RzTypeParser *parser, const ch
|
|||
|
||||
// If there were errors during the parser then the result is different from 0
|
||||
if (result || !tpair) {
|
||||
const char *error_msgs = rz_strbuf_drain_nofree(parser->state->errors);
|
||||
char *error_msgs = rz_strbuf_drain_nofree(parser->state->errors);
|
||||
RZ_LOG_DEBUG("Errors:\n");
|
||||
RZ_LOG_DEBUG("%s", error_msgs);
|
||||
const char *warning_msgs = rz_strbuf_drain_nofree(parser->state->warnings);
|
||||
char *warning_msgs = rz_strbuf_drain_nofree(parser->state->warnings);
|
||||
RZ_LOG_DEBUG("Warnings:\n");
|
||||
RZ_LOG_DEBUG("%s", warning_msgs);
|
||||
if (error_msg) {
|
||||
*error_msg = strdup(error_msgs);
|
||||
}
|
||||
free(error_msgs);
|
||||
free(warning_msgs);
|
||||
}
|
||||
if (parser->state->verbose) {
|
||||
char *debug_msgs = rz_strbuf_drain_nofree(parser->state->debug);
|
||||
|
|
@ -439,19 +450,22 @@ RZ_API RZ_OWN RzType *rz_type_parse_string_declaration_single(RzTypeParser *pars
|
|||
|
||||
// If there were errors during the parser then the result is different from 0
|
||||
if (result || !tpair) {
|
||||
const char *error_msgs = rz_strbuf_drain_nofree(parser->state->errors);
|
||||
char *error_msgs = rz_strbuf_drain_nofree(parser->state->errors);
|
||||
RZ_LOG_DEBUG("Errors:\n");
|
||||
RZ_LOG_DEBUG("%s", error_msgs);
|
||||
const char *warning_msgs = rz_strbuf_drain_nofree(parser->state->warnings);
|
||||
char *warning_msgs = rz_strbuf_drain_nofree(parser->state->warnings);
|
||||
RZ_LOG_DEBUG("Warnings:\n");
|
||||
RZ_LOG_DEBUG("%s", warning_msgs);
|
||||
if (error_msg) {
|
||||
*error_msg = strdup(error_msgs);
|
||||
}
|
||||
free(error_msgs);
|
||||
free(warning_msgs);
|
||||
}
|
||||
if (parser->state->verbose) {
|
||||
const char *debug_msgs = rz_strbuf_drain_nofree(parser->state->debug);
|
||||
char *debug_msgs = rz_strbuf_drain_nofree(parser->state->debug);
|
||||
RZ_LOG_DEBUG("%s", debug_msgs);
|
||||
free(debug_msgs);
|
||||
}
|
||||
|
||||
// After everything parsed, we should preserve the base type database
|
||||
|
|
|
|||
|
|
@ -347,20 +347,20 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser
|
|||
if (!(*tpair = c_parser_new_structure_naked_type(state, name))) {
|
||||
parser_error(state, "Cannot create \"%s\" naked structure type in the context\n", name);
|
||||
result = -1;
|
||||
goto rexit;
|
||||
goto snexit;
|
||||
}
|
||||
goto rexit;
|
||||
goto snexit;
|
||||
}
|
||||
// We still could create the "forward looking struct declaration"
|
||||
// The parser then can augment the definition
|
||||
if (!(*tpair = c_parser_new_structure_forward_definition(state, name))) {
|
||||
parser_error(state, "Cannot create \"%s\" forward structure definition in the context\n", name);
|
||||
result = -1;
|
||||
goto rexit;
|
||||
goto snexit;
|
||||
}
|
||||
goto rexit;
|
||||
goto snexit;
|
||||
} else {
|
||||
goto rexit;
|
||||
goto snexit;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -377,8 +377,11 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser
|
|||
if (!struct_pair) {
|
||||
parser_error(state, "Error forming RzType and RzBaseType pair out of struct: \"%s\"\n", name);
|
||||
result = -1;
|
||||
goto rexit;
|
||||
goto snexit;
|
||||
}
|
||||
|
||||
char *real_type = NULL;
|
||||
char *real_identifier = NULL;
|
||||
int i;
|
||||
for (i = 0; i < body_child_count; i++) {
|
||||
parser_debug(state, "struct: processing %d field...\n", i);
|
||||
|
|
@ -392,7 +395,7 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser
|
|||
if (ts_node_is_null(first_leaf)) {
|
||||
node_malformed_error(state, child, text, "field_declaration");
|
||||
result = -1;
|
||||
goto rexit;
|
||||
goto snexit;
|
||||
}
|
||||
const char *leaf_type = ts_node_type(first_leaf);
|
||||
// If we have type qualifier in this position it is related to
|
||||
|
|
@ -412,7 +415,7 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser
|
|||
parser_error(state, "ERROR: Struct field AST should contain (field_declaration) node!\n");
|
||||
node_malformed_error(state, child, text, "struct field");
|
||||
result = -1;
|
||||
goto rexit;
|
||||
goto snexit;
|
||||
}
|
||||
|
||||
// Every field node should have at least type and declarator:
|
||||
|
|
@ -422,8 +425,9 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser
|
|||
parser_error(state, "ERROR: Struct field AST shoudl contain type and declarator items");
|
||||
node_malformed_error(state, child, text, "struct field");
|
||||
result = -1;
|
||||
goto rexit;
|
||||
goto snexit;
|
||||
}
|
||||
|
||||
// Every field can be:
|
||||
// - atomic: "int a;" or "char b[20]"
|
||||
// - bitfield: int a:7;"
|
||||
|
|
@ -449,33 +453,34 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser
|
|||
parser_error(state, "ERROR: Struct bitfield cannot contain non-primitive bitfield!\n");
|
||||
node_malformed_error(state, child, text, "struct field");
|
||||
result = -1;
|
||||
goto rexit;
|
||||
goto snexit;
|
||||
}
|
||||
const char *real_type = ts_node_sub_string(field_type, text);
|
||||
real_type = ts_node_sub_string(field_type, text);
|
||||
if (!real_type) {
|
||||
parser_error(state, "ERROR: Struct bitfield type should not be NULL!\n");
|
||||
node_malformed_error(state, child, text, "struct field");
|
||||
result = -1;
|
||||
goto rexit;
|
||||
goto snexit;
|
||||
}
|
||||
const char *real_identifier = ts_node_sub_string(field_declarator, text);
|
||||
real_identifier = ts_node_sub_string(field_declarator, text);
|
||||
if (!real_identifier) {
|
||||
parser_error(state, "ERROR: Struct bitfield identifier should not be NULL!\n");
|
||||
node_malformed_error(state, child, text, "struct field");
|
||||
free(real_type);
|
||||
result = -1;
|
||||
goto rexit;
|
||||
goto snexit;
|
||||
}
|
||||
if (ts_node_named_child_count(bitfield_clause) != 1) {
|
||||
node_malformed_error(state, child, text, "struct field");
|
||||
result = -1;
|
||||
goto rexit;
|
||||
goto srnexit;
|
||||
}
|
||||
TSNode field_bits = ts_node_named_child(bitfield_clause, 0);
|
||||
if (ts_node_is_null(field_bits)) {
|
||||
parser_error(state, "ERROR: Struct bitfield bits AST node should not be NULL!\n");
|
||||
node_malformed_error(state, child, text, "struct field");
|
||||
result = -1;
|
||||
goto rexit;
|
||||
goto srnexit;
|
||||
}
|
||||
const char *bits_str = ts_node_sub_string(field_bits, text);
|
||||
int bits = rz_num_get(NULL, bits_str);
|
||||
|
|
@ -485,7 +490,7 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser
|
|||
parser_error(state, "ERROR: parsing bitfield struct member identifier\n");
|
||||
node_malformed_error(state, child, text, "struct field");
|
||||
result = -1;
|
||||
goto rexit;
|
||||
goto srnexit;
|
||||
}
|
||||
// Then we augment resulting type field with the data from parsed declarator
|
||||
char *membname = NULL;
|
||||
|
|
@ -493,7 +498,7 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser
|
|||
parser_error(state, "ERROR: parsing bitfield struct member declarator\n");
|
||||
node_malformed_error(state, child, text, "struct field");
|
||||
result = -1;
|
||||
goto rexit;
|
||||
goto srnexit;
|
||||
}
|
||||
// Add a struct member
|
||||
RzVector *members = &struct_pair->btype->struct_data.members;
|
||||
|
|
@ -507,25 +512,26 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser
|
|||
if (!element) {
|
||||
parser_error(state, "Error appending bitfield struct member to the base type\n");
|
||||
result = -1;
|
||||
goto rexit;
|
||||
goto srnexit;
|
||||
}
|
||||
} else {
|
||||
// 2nd case, normal structure
|
||||
// AST looks like
|
||||
// type: (primitive_type) declarator: (field_identifier)
|
||||
char *real_type = ts_node_sub_string(field_type, text);
|
||||
real_type = ts_node_sub_string(field_type, text);
|
||||
if (!real_type) {
|
||||
parser_error(state, "ERROR: Struct field type should not be NULL!\n");
|
||||
node_malformed_error(state, child, text, "struct field");
|
||||
result = -1;
|
||||
goto rexit;
|
||||
goto snexit;
|
||||
}
|
||||
char *real_identifier = ts_node_sub_string(field_declarator, text);
|
||||
real_identifier = ts_node_sub_string(field_declarator, text);
|
||||
if (!real_identifier) {
|
||||
parser_error(state, "ERROR: Struct declarator should not be NULL!\n");
|
||||
node_malformed_error(state, child, text, "struct field");
|
||||
free(real_type);
|
||||
result = -1;
|
||||
goto rexit;
|
||||
goto snexit;
|
||||
}
|
||||
parser_debug(state, "field type: %s field_declarator: %s\n", real_type, real_identifier);
|
||||
ParserTypePair *membtpair = NULL;
|
||||
|
|
@ -533,20 +539,16 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser
|
|||
if (parse_type_node_single(state, field_type, text, &membtpair, is_const)) {
|
||||
parser_error(state, "ERROR: parsing struct member type\n");
|
||||
node_malformed_error(state, child, text, "struct field");
|
||||
free(real_identifier);
|
||||
free(real_type);
|
||||
result = -1;
|
||||
goto rexit;
|
||||
goto srnexit;
|
||||
}
|
||||
// Then we augment resulting type field with the data from parsed declarator
|
||||
char *membname = NULL;
|
||||
if (parse_type_declarator_node(state, field_declarator, text, &membtpair, &membname)) {
|
||||
parser_error(state, "ERROR: parsing struct member declarator\n");
|
||||
node_malformed_error(state, child, text, "struct field");
|
||||
free(real_identifier);
|
||||
free(real_type);
|
||||
result = -1;
|
||||
goto rexit;
|
||||
goto srnexit;
|
||||
}
|
||||
// Add a struct member
|
||||
RzVector *members = &struct_pair->btype->struct_data.members;
|
||||
|
|
@ -559,14 +561,10 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser
|
|||
void *element = rz_vector_push(members, &memb); // returns null if no space available
|
||||
if (!element) {
|
||||
parser_error(state, "Error appending struct member to the base type\n");
|
||||
free(real_identifier);
|
||||
free(real_type);
|
||||
result = -1;
|
||||
goto rexit;
|
||||
goto srnexit;
|
||||
}
|
||||
parser_debug(state, "Appended member \"%s\" into struct \"%s\"\n", membname, name);
|
||||
free(real_identifier);
|
||||
free(real_type);
|
||||
}
|
||||
}
|
||||
// If parsing successfull completed - we store the state
|
||||
|
|
@ -578,7 +576,10 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser
|
|||
}
|
||||
}
|
||||
*tpair = struct_pair;
|
||||
rexit:
|
||||
srnexit:
|
||||
free(real_type);
|
||||
free(real_identifier);
|
||||
snexit:
|
||||
free(name);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -597,8 +598,9 @@ int parse_union_node(CParserState *state, TSNode node, const char *text, ParserT
|
|||
node_malformed_error(state, node, text, "union");
|
||||
return -1;
|
||||
}
|
||||
int result = 0;
|
||||
// Name is optional, in abstract definitions or as the member of nested types
|
||||
const char *name = NULL;
|
||||
char *name = NULL;
|
||||
TSNode union_name = ts_node_child_by_field_name(node, "name", 4);
|
||||
if (ts_node_is_null(union_name)) {
|
||||
parser_debug(state, "Anonymous union\n");
|
||||
|
|
@ -657,6 +659,9 @@ int parse_union_node(CParserState *state, TSNode node, const char *text, ParserT
|
|||
parser_error(state, "Error forming RzType and RzBaseType pair out of union\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *real_type = NULL;
|
||||
char *real_identifier = NULL;
|
||||
int i;
|
||||
for (i = 0; i < body_child_count; i++) {
|
||||
parser_debug(state, "union: processing %d field...\n", i);
|
||||
|
|
@ -723,52 +728,53 @@ int parse_union_node(CParserState *state, TSNode node, const char *text, ParserT
|
|||
if (strcmp(ts_node_type(field_type), "primitive_type")) {
|
||||
parser_error(state, "ERROR: Union bitfield cannot contain non-primitive bitfield!\n");
|
||||
node_malformed_error(state, child, text, "union field");
|
||||
return -1;
|
||||
result = -1;
|
||||
goto unexit;
|
||||
}
|
||||
char *real_type = ts_node_sub_string(field_type, text);
|
||||
real_type = ts_node_sub_string(field_type, text);
|
||||
if (!real_type) {
|
||||
parser_error(state, "ERROR: Union bitfield type should not be NULL!\n");
|
||||
node_malformed_error(state, child, text, "union field");
|
||||
return -1;
|
||||
result = -1;
|
||||
goto unexit;
|
||||
}
|
||||
char *real_identifier = ts_node_sub_string(field_declarator, text);
|
||||
real_identifier = ts_node_sub_string(field_declarator, text);
|
||||
if (!real_identifier) {
|
||||
parser_error(state, "ERROR: Union bitfield identifier should not be NULL!\n");
|
||||
node_malformed_error(state, child, text, "union field");
|
||||
free(real_type);
|
||||
return -1;
|
||||
result = -1;
|
||||
goto unexit;
|
||||
}
|
||||
if (ts_node_named_child_count(bitfield_clause) != 1) {
|
||||
node_malformed_error(state, child, text, "union field");
|
||||
free(real_type);
|
||||
free(real_identifier);
|
||||
return -1;
|
||||
result = -1;
|
||||
goto urnexit;
|
||||
}
|
||||
TSNode field_bits = ts_node_named_child(bitfield_clause, 0);
|
||||
if (ts_node_is_null(field_bits)) {
|
||||
parser_error(state, "ERROR: Union bitfield bits AST node should not be NULL!\n");
|
||||
node_malformed_error(state, child, text, "union field");
|
||||
free(real_type);
|
||||
free(real_identifier);
|
||||
return -1;
|
||||
result = -1;
|
||||
goto urnexit;
|
||||
}
|
||||
const char *bits_str = ts_node_sub_string(field_bits, text);
|
||||
int bits = rz_num_get(NULL, bits_str);
|
||||
parser_debug(state, "field type: %s field_identifier: %s bits: %d\n", real_type, real_identifier, bits);
|
||||
free(real_type);
|
||||
free(real_identifier);
|
||||
ParserTypePair *membtpair = NULL;
|
||||
if (parse_type_node_single(state, field_type, text, &membtpair, is_const)) {
|
||||
parser_error(state, "ERROR: parsing union member identifier\n");
|
||||
node_malformed_error(state, child, text, "union field");
|
||||
return -1;
|
||||
result = -1;
|
||||
goto urnexit;
|
||||
}
|
||||
// Then we augment resulting type field with the data from parsed declarator
|
||||
char *membname = NULL;
|
||||
if (parse_type_declarator_node(state, field_declarator, text, &membtpair, &membname)) {
|
||||
parser_error(state, "ERROR: parsing union member declarator\n");
|
||||
node_malformed_error(state, child, text, "union field");
|
||||
return -1;
|
||||
result = -1;
|
||||
goto urnexit;
|
||||
}
|
||||
// Add a union member
|
||||
RzVector *members = &union_pair->btype->union_data.members;
|
||||
|
|
@ -781,24 +787,27 @@ int parse_union_node(CParserState *state, TSNode node, const char *text, ParserT
|
|||
void *element = rz_vector_push(members, &memb); // returns null if no space available
|
||||
if (!element) {
|
||||
parser_error(state, "Error appending union member to the base type\n");
|
||||
return -1;
|
||||
result = -1;
|
||||
goto urnexit;
|
||||
}
|
||||
} else {
|
||||
// 2nd case, normal union
|
||||
// AST looks like
|
||||
// type: (primitive_type) declarator: (field_identifier)
|
||||
char *real_type = ts_node_sub_string(field_type, text);
|
||||
real_type = ts_node_sub_string(field_type, text);
|
||||
if (!real_type) {
|
||||
parser_error(state, "ERROR: Union field type should not be NULL!\n");
|
||||
node_malformed_error(state, child, text, "union field");
|
||||
return -1;
|
||||
result = -1;
|
||||
goto unexit;
|
||||
}
|
||||
char *real_identifier = ts_node_sub_string(field_declarator, text);
|
||||
real_identifier = ts_node_sub_string(field_declarator, text);
|
||||
if (!real_identifier) {
|
||||
parser_error(state, "ERROR: Union declarator should not be NULL!\n");
|
||||
node_malformed_error(state, child, text, "union field");
|
||||
free(real_type);
|
||||
return -1;
|
||||
result = -1;
|
||||
goto unexit;
|
||||
}
|
||||
parser_debug(state, "field type: %s field_declarator: %s\n", real_type, real_identifier);
|
||||
ParserTypePair *membtpair = NULL;
|
||||
|
|
@ -806,18 +815,16 @@ int parse_union_node(CParserState *state, TSNode node, const char *text, ParserT
|
|||
if (parse_type_node_single(state, field_type, text, &membtpair, is_const)) {
|
||||
parser_error(state, "ERROR: parsing union member type\n");
|
||||
node_malformed_error(state, child, text, "union field");
|
||||
free(real_identifier);
|
||||
free(real_type);
|
||||
return -1;
|
||||
result = -1;
|
||||
goto urnexit;
|
||||
}
|
||||
// Then we augment resulting type field with the data from parsed declarator
|
||||
char *membname = NULL;
|
||||
if (parse_type_declarator_node(state, field_declarator, text, &membtpair, &membname)) {
|
||||
parser_error(state, "ERROR: parsing union member declarator\n");
|
||||
node_malformed_error(state, child, text, "union field");
|
||||
free(real_identifier);
|
||||
free(real_type);
|
||||
return -1;
|
||||
result = -1;
|
||||
goto urnexit;
|
||||
}
|
||||
// Add a union member
|
||||
RzVector *members = &union_pair->btype->union_data.members;
|
||||
|
|
@ -830,12 +837,9 @@ int parse_union_node(CParserState *state, TSNode node, const char *text, ParserT
|
|||
void *element = rz_vector_push(members, &memb); // returns null if no space available
|
||||
if (!element) {
|
||||
parser_error(state, "Error appending union member to the base type\n");
|
||||
free(real_identifier);
|
||||
free(real_type);
|
||||
return -1;
|
||||
result = -1;
|
||||
goto urnexit;
|
||||
}
|
||||
free(real_identifier);
|
||||
free(real_type);
|
||||
}
|
||||
}
|
||||
// If parsing successfull completed - we store the state
|
||||
|
|
@ -847,7 +851,12 @@ int parse_union_node(CParserState *state, TSNode node, const char *text, ParserT
|
|||
}
|
||||
}
|
||||
*tpair = union_pair;
|
||||
return 0;
|
||||
urnexit:
|
||||
free(real_type);
|
||||
free(real_identifier);
|
||||
unexit:
|
||||
free(name);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Parsing enum definitions - concrete and abstract ones
|
||||
|
|
@ -1225,6 +1234,7 @@ int parse_parameter_list(CParserState *state, TSNode paramlist, const char *text
|
|||
free(identifier);
|
||||
return -1;
|
||||
}
|
||||
free(identifier);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue