From 09a3e257e87045fd4c49d56b0e3459fe2f81d461 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 26 May 2023 21:56:19 +0900 Subject: [PATCH] [qfcc] Fully initialize local structural defs I think the current build_element_chain implementation does a reasonable job, but I'm in the process of getting designated initializers working, thus it will become important to ensure uninitialized members get initialized. --- tools/qfcc/include/expr.h | 3 ++- tools/qfcc/source/expr.c | 13 ++++++++++++- tools/qfcc/source/expr_compound.c | 21 +++++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index 43dc6a255..b2b7631f3 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -142,7 +142,6 @@ typedef struct ex_memset_s { struct expr_s *dst; struct expr_s *val; struct expr_s *count; - struct type_s *type; } ex_memset_t; /** State expression used for think function state-machines. @@ -778,6 +777,8 @@ expr_t *new_with_expr (int mode, int reg, expr_t *val); */ expr_t *new_param_expr (struct type_s *type, int num); +expr_t *new_memset_expr (expr_t *dst, expr_t *val, expr_t *count); + /** Convert a name to an expression of the appropriate type. Converts the expression in-place. If the exprssion is not a name diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index deec20857..3e25ee5b1 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -140,7 +140,7 @@ get_type (expr_t *e) case ex_with: return &type_void; case ex_memset: - return e->e.memset.type; + return 0; case ex_error: return 0; case ex_return: @@ -1374,6 +1374,17 @@ new_param_expr (type_t *type, int num) return param_expr (va (0, ".param_%d", num), type); } +expr_t * +new_memset_expr (expr_t *dst, expr_t *val, expr_t *count) +{ + expr_t *e = new_expr (); + e->type = ex_memset; + e->e.memset.dst = dst; + e->e.memset.val = val; + e->e.memset.count = count; + return e; +} + expr_t * append_expr (expr_t *block, expr_t *e) { diff --git a/tools/qfcc/source/expr_compound.c b/tools/qfcc/source/expr_compound.c index 2ba6f489a..eb5dafae8 100644 --- a/tools/qfcc/source/expr_compound.c +++ b/tools/qfcc/source/expr_compound.c @@ -42,6 +42,7 @@ #include "QF/alloc.h" #include "QF/dstring.h" #include "QF/mathlib.h" +#include "QF/set.h" #include "QF/sys.h" #include "QF/va.h" @@ -189,6 +190,8 @@ assign_elements (expr_t *local_expr, expr_t *init, element_chain_t *element_chain) { element_t *element; + type_t *init_type = get_type (init); + set_t *initialized = set_new_size (type_size (init_type)); for (element = element_chain->head; element; element = element->next) { int offset = element->offset; @@ -206,7 +209,25 @@ assign_elements (expr_t *local_expr, expr_t *init, c = convert_nil (c, type); } append_expr (local_expr, assign_expr (alias, c)); + set_add_range (initialized, offset, type_size (type)); } + + unsigned start = 0; + for (set_iter_t *in = set_first (initialized); in; in = set_next (in)) { + unsigned end = in->element; + if (end > start) { + expr_t *dst = new_offset_alias_expr (&type_int, init, start); + expr_t *zero = new_int_expr (0); + expr_t *count = new_int_expr (end - start); + append_expr (local_expr, new_memset_expr (dst, zero, count)); + } + // skip over all the initialized locations + in = set_while (in); + if (in) { + start = in->element; + } + } + set_delete (initialized); } expr_t *