From ba83e861566d75132074fabfc96eff5e30e34297 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Mon, 8 Feb 2016 16:13:28 +0100 Subject: [PATCH] dissect: teach do_initializer() to handle the nested EXPR_IDENTIFIER's do_initializer() is very limited/buggy but it was able to parse the kernel code until ftrace started to use ".a.b = x" rather than ".a = { .b = x }" in initializers. Test-case: struct O { struct I { int mem; } inn; int end; } var = { .inn.mem = 0, 0, }; before the patch: 1:8 s def O 2:16 s def I 6:3 g def var struct O 6:3 g -w- var struct O 7:10 s -w- O.inn struct I 7:10 s -w- I.* struct I I.c:7:14: warning: bad expr->type: 25 8:9 s -w- O.end int after: 1:8 s def O 2:16 s def I 6:3 g def var struct O 6:3 g -w- var struct O 7:10 s -w- O.inn struct I 7:14 s -w- I.mem int 8:9 s -w- O.end int Signed-off-by: Oleg Nesterov Acked-by: Lance Richardson Signed-off-by: Christopher Li --- dissect.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/dissect.c b/dissect.c index 19f32763..2d13d2a3 100644 --- a/dissect.c +++ b/dissect.c @@ -547,18 +547,23 @@ static struct symbol *do_initializer(struct symbol *type, struct expression *exp if (m_expr->type == EXPR_INDEX) m_expr = m_expr->idx_expression; } else { - struct position *pos = &m_expr->pos; - struct ident *m_name = NULL; + int *m_atop = &m_addr; - if (m_expr->type == EXPR_IDENTIFIER) { - m_name = m_expr->expr_ident; + m_type = type; + while (m_expr->type == EXPR_IDENTIFIER) { + m_type = report_member(U_W_VAL, &m_expr->pos, m_type, + lookup_member(m_type, m_expr->expr_ident, m_atop)); m_expr = m_expr->ident_expression; + m_atop = NULL; + } + + if (m_atop) { + m_type = report_member(U_W_VAL, &m_expr->pos, m_type, + lookup_member(m_type, NULL, m_atop)); } - m_type = report_member(U_W_VAL, pos, type, - lookup_member(type, m_name, &m_addr)); if (m_expr->type != EXPR_INITIALIZER) - report_implicit(U_W_VAL, pos, m_type); + report_implicit(U_W_VAL, &m_expr->pos, m_type); } do_initializer(m_type, m_expr); m_addr++; -- 2.11.4.GIT