Currently, constant_symbol_value() is doing the expansion of a constant initializer when an explicit one is found but nothing is done if the initilizer is an implicit one. Fix this by: * adding an helper to lookup the corresponding type from offset; * using this helper to get the correct kind for the value: - a 0-valued EXPR_VALUE for integers - a 0.0-valued EXPR_FVALUE for floats. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- expand.c | 65 ++++++++++++++++++++++++- validation/expand/default-init-struct.c | 1 - 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/expand.c b/expand.c index 9ab259b13a82..cd348bf5833e 100644 --- a/expand.c +++ b/expand.c @@ -621,6 +621,66 @@ static int expand_addressof(struct expression *expr) return expand_expression(expr->unop); } +/// +// lookup the type of a struct's memeber at the requested offset +static struct symbol *find_member(struct symbol *sym, int offset) +{ + struct ptr_list *head, *list; + + head = (struct ptr_list *) sym->symbol_list; + list = head; + if (!head) + return NULL; + do { + int nr = list->nr; + int i; + for (i = 0; i < nr; i++) { + struct symbol *ent = (struct symbol *) list->list[i]; + int curr = ent->offset; + if (curr == offset) + return ent; + if (curr > offset) + return NULL; + } + } while ((list = list->next) != head); + return NULL; +} + +/// +// lookup a suitable default initializer value at the requested offset +static struct expression *default_initializer(struct symbol *sym, int offset) +{ + static struct expression value; + struct symbol *type; + +redo: + switch (sym->type) { + case SYM_NODE: + sym = sym->ctype.base_type; + goto redo; + case SYM_STRUCT: + type = find_member(sym, offset); + if (!type) + return NULL; + break; + case SYM_ARRAY: + type = sym->ctype.base_type; + break; + default: + return NULL; + } + + if (is_integral_type(type)) + value.type = EXPR_VALUE; + else if (is_float_type(type)) + value.type = EXPR_FVALUE; + else + return NULL; + + value.ctype = type; + return &value; +} + /* * Look up a trustable initializer value at the requested offset. * @@ -646,10 +706,11 @@ static struct expression *constant_symbol_value(struct symbol *sym, int offset) if (entry->init_offset < offset) continue; if (entry->init_offset > offset) - return NULL; + break; return entry->init_expr; } END_FOR_EACH_PTR(entry); - return NULL; + + value = default_initializer(sym, offset); } return value; } diff --git a/validation/expand/default-init-struct.c b/validation/expand/default-init-struct.c index c843a1abb960..085dd2d6dca9 100644 --- a/validation/expand/default-init-struct.c +++ b/validation/expand/default-init-struct.c @@ -15,7 +15,6 @@ int test_struct(void) /* * check-name: default-init-struct * check-command: test-linearize -Wno-decl -fdump-ir $file - * check-known-to-fail * * check-output-ignore * check-output-contains: phisrc\\..*return.*\\$0 -- 2.24.0